forked from rpms/glibc
		
	- Sort objects before relocations (sw#13618)
- Fix bogus sort code that was copied from dl-deps.c.
This commit is contained in:
		
							parent
							
								
									61e27a5181
								
							
						
					
					
						commit
						70c5758f43
					
				
							
								
								
									
										28
									
								
								glibc-sw13618-2.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								glibc-sw13618-2.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,28 @@ | ||||
| diff -Nrup a/elf/dl-open.c b/elf/dl-open.c
 | ||||
| --- a/elf/dl-open.c	2012-01-29 21:57:36.251660367 -0700
 | ||||
| +++ b/elf/dl-open.c	2012-01-29 21:58:55.762694069 -0700
 | ||||
| @@ -328,7 +328,7 @@ dl_open_worker (void *a)
 | ||||
|    while (l != NULL); | ||||
|    if (nmaps > 1) | ||||
|      { | ||||
| -      char seen[nmaps];
 | ||||
| +      uint16_t seen[nmaps];
 | ||||
|        memset (seen, '\0', nmaps); | ||||
|        size_t i = 0; | ||||
|        while (1) | ||||
| @@ -354,13 +354,13 @@ dl_open_worker (void *a)
 | ||||
|  			       (k - i) * sizeof (maps[0])); | ||||
|  		      maps[k] = thisp; | ||||
|   | ||||
| -		      if (seen[i + 1] > 1)
 | ||||
| +		      if (seen[i + 1] > nmaps - i)
 | ||||
|  			{ | ||||
|  			  ++i; | ||||
|  			  goto next_clear; | ||||
|  			} | ||||
|   | ||||
| -		      char this_seen = seen[i];
 | ||||
| +		      uint16_t this_seen = seen[i];
 | ||||
|  		      memmove (&seen[i], &seen[i + 1], | ||||
|  			       (k - i) * sizeof (seen[0])); | ||||
|  		      seen[k] = this_seen; | ||||
							
								
								
									
										267
									
								
								glibc-sw13618.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										267
									
								
								glibc-sw13618.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,267 @@ | ||||
| diff -Nrup a/Makeconfig b/Makeconfig
 | ||||
| --- a/Makeconfig	2012-01-29 21:44:43.010328202 -0700
 | ||||
| +++ b/Makeconfig	2012-01-29 21:45:18.242344330 -0700
 | ||||
| @@ -950,6 +950,12 @@ libdl =
 | ||||
|  endif | ||||
|  endif | ||||
|   | ||||
| +ifeq ($(build-shared),yes)
 | ||||
| +libm = $(common-objpfx)math/libm.so$(libm.so-version)
 | ||||
| +else
 | ||||
| +libm = $(common-objpfx)math/libm.a
 | ||||
| +endif
 | ||||
| +
 | ||||
|  # These are the subdirectories containing the library source.  The order | ||||
|  # is more or less arbitrary.  The sorting step will take care of the | ||||
|  # dependencies. | ||||
| diff -Nrup a/elf/Makefile b/elf/Makefile
 | ||||
| --- a/elf/Makefile	2012-01-29 21:44:43.087328238 -0700
 | ||||
| +++ b/elf/Makefile	2012-01-29 21:45:18.880344622 -0700
 | ||||
| @@ -124,7 +124,8 @@ distribute	:= rtld-Rules \
 | ||||
|  		   tst-initordera1.c tst-initordera2.c tst-initorderb1.c \ | ||||
|  		   tst-initorderb2.c tst-initordera3.c tst-initordera4.c \ | ||||
|  		   tst-initorder.c \ | ||||
| -		   tst-initorder2.c
 | ||||
| +		   tst-initorder2.c \
 | ||||
| +		   tst-relsort1.c tst-relsort1mod1.c tst-relsort1mod2.c
 | ||||
|   | ||||
|  CFLAGS-dl-runtime.c = -fexceptions -fasynchronous-unwind-tables | ||||
|  CFLAGS-dl-lookup.c = -fexceptions -fasynchronous-unwind-tables | ||||
| @@ -230,7 +231,7 @@ tests += loadtest restest1 preloadtest l
 | ||||
|  	 tst-audit1 tst-audit2 \ | ||||
|  	 tst-stackguard1 tst-addr1 tst-thrlock \ | ||||
|  	 tst-unique1 tst-unique2 tst-unique3 tst-unique4 \ | ||||
| -	 tst-initorder tst-initorder2
 | ||||
| +	 tst-initorder tst-initorder2 tst-relsort1
 | ||||
|  #	 reldep9 | ||||
|  test-srcs = tst-pathopt | ||||
|  selinux-enabled := $(shell cat /selinux/enforce 2> /dev/null) | ||||
| @@ -293,7 +294,9 @@ modules-names = testobj1 testobj2 testob
 | ||||
|  		tst-initordera1 tst-initorderb1 \ | ||||
|  		tst-initordera2 tst-initorderb2 \ | ||||
|  		tst-initordera3 tst-initordera4 \ | ||||
| -		tst-initorder2a tst-initorder2b tst-initorder2c tst-initorder2d
 | ||||
| +		tst-initorder2a tst-initorder2b tst-initorder2c \
 | ||||
| +		tst-initorder2d \
 | ||||
| +		tst-relsort1mod1 tst-relsort1mod2
 | ||||
|  ifeq (yes,$(have-initfini-array)) | ||||
|  modules-names += tst-array2dep tst-array5dep | ||||
|  endif | ||||
| @@ -1199,3 +1202,9 @@ CFLAGS-tst-auditmod6b.c += $(AVX-CFLAGS)
 | ||||
|  CFLAGS-tst-auditmod6c.c += $(AVX-CFLAGS) | ||||
|  CFLAGS-tst-auditmod7b.c += $(AVX-CFLAGS) | ||||
|  endif | ||||
| +
 | ||||
| +$(objpfx)tst-relsort1: $(libdl)
 | ||||
| +$(objpfx)tst-relsort1mod1.so: $(libm) $(objpfx)tst-relsort1mod2.so
 | ||||
| +$(objpfx)tst-relsort1mod2.so: $(libm)
 | ||||
| +$(objpfx)tst-relsort1.out: $(objpfx)tst-relsort1mod1.so \
 | ||||
| +			   $(objpfx)tst-relsort1mod2.so
 | ||||
| diff -Nrup a/elf/dl-open.c b/elf/dl-open.c
 | ||||
| --- a/elf/dl-open.c	2012-01-29 21:44:43.165328272 -0700
 | ||||
| +++ b/elf/dl-open.c	2012-01-29 21:55:06.683599515 -0700
 | ||||
| @@ -1,5 +1,5 @@
 | ||||
|  /* Load a shared object at runtime, relocate it, and run its initializer. | ||||
| -   Copyright (C) 1996-2007, 2009, 2010, 2011 Free Software Foundation, Inc.
 | ||||
| +   Copyright (C) 1996-2007, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
 | ||||
|     This file is part of the GNU C Library. | ||||
|   | ||||
|     The GNU C Library is free software; you can redistribute it and/or | ||||
| @@ -304,53 +304,116 @@ dl_open_worker (void *a)
 | ||||
|    if (GLRO(dl_lazy)) | ||||
|      reloc_mode |= mode & RTLD_LAZY; | ||||
|   | ||||
| -  /* Relocate the objects loaded.  We do this in reverse order so that copy
 | ||||
| -     relocs of earlier objects overwrite the data written by later objects.  */
 | ||||
| -
 | ||||
| +  /* Sort the objects by dependency for the relocation process.  This
 | ||||
| +     allows IFUNC relocations to work and it also means copy
 | ||||
| +     relocation of dependencies are if necessary overwritten.  */
 | ||||
| +  size_t nmaps = 0;
 | ||||
|    struct link_map *l = new; | ||||
| -  while (l->l_next)
 | ||||
| -    l = l->l_next;
 | ||||
| -  int relocation_in_progress = 0;
 | ||||
| -  while (1)
 | ||||
| +  do
 | ||||
|      { | ||||
|        if (! l->l_real->l_relocated) | ||||
| +	++nmaps;
 | ||||
| +      l = l->l_next;
 | ||||
| +    }
 | ||||
| +  while (l != NULL);
 | ||||
| +  struct link_map *maps[nmaps];
 | ||||
| +  nmaps = 0;
 | ||||
| +  l = new;
 | ||||
| +  do
 | ||||
| +    {
 | ||||
| +      if (! l->l_real->l_relocated)
 | ||||
| +	maps[nmaps++] = l;
 | ||||
| +      l = l->l_next;
 | ||||
| +    }
 | ||||
| +  while (l != NULL);
 | ||||
| +  if (nmaps > 1)
 | ||||
| +    {
 | ||||
| +      char seen[nmaps];
 | ||||
| +      memset (seen, '\0', nmaps);
 | ||||
| +      size_t i = 0;
 | ||||
| +      while (1)
 | ||||
|  	{ | ||||
| -	  if (! relocation_in_progress)
 | ||||
| +	  ++seen[i];
 | ||||
| +	  struct link_map *thisp = maps[i];
 | ||||
| +
 | ||||
| +	  /* Find the last object in the list for which the current one is
 | ||||
| +	     a dependency and move the current object behind the object
 | ||||
| +	     with the dependency.  */
 | ||||
| +	  size_t k = nmaps - 1;
 | ||||
| +	  while (k > i)
 | ||||
|  	    { | ||||
| -	      /* Notify the debugger that relocations are about to happen.  */
 | ||||
| -	      LIBC_PROBE (rtld_reloc_start, 2, args->nsid, r);
 | ||||
| -	      relocation_in_progress = 1;
 | ||||
| +	      struct link_map **runp = maps[k]->l_initfini;
 | ||||
| +	      if (runp != NULL)
 | ||||
| +		/* Look through the dependencies of the object.  */
 | ||||
| +		while (*runp != NULL)
 | ||||
| +		  if (__builtin_expect (*runp++ == thisp, 0))
 | ||||
| +		    {
 | ||||
| +		      /* Move the current object to the back past the last
 | ||||
| +			 object with it as the dependency.  */
 | ||||
| +		      memmove (&maps[i], &maps[i + 1],
 | ||||
| +			       (k - i) * sizeof (maps[0]));
 | ||||
| +		      maps[k] = thisp;
 | ||||
| +
 | ||||
| +		      if (seen[i + 1] > 1)
 | ||||
| +			{
 | ||||
| +			  ++i;
 | ||||
| +			  goto next_clear;
 | ||||
| +			}
 | ||||
| +
 | ||||
| +		      char this_seen = seen[i];
 | ||||
| +		      memmove (&seen[i], &seen[i + 1],
 | ||||
| +			       (k - i) * sizeof (seen[0]));
 | ||||
| +		      seen[k] = this_seen;
 | ||||
| +
 | ||||
| +		      goto next;
 | ||||
| +		    }
 | ||||
| +
 | ||||
| +	      --k;
 | ||||
|  	    } | ||||
|   | ||||
| +	  if (++i == nmaps)
 | ||||
| +	    break;
 | ||||
| +	next_clear:
 | ||||
| +	  memset (&seen[i], 0, (nmaps - i) * sizeof (seen[0]));
 | ||||
| +	next:;
 | ||||
| +	}
 | ||||
| +    }
 | ||||
| +
 | ||||
| +  int relocation_in_progress = 0;
 | ||||
| +  for (size_t i = nmaps; i-- > 0; )
 | ||||
| +    {
 | ||||
| +      l = maps[i];
 | ||||
| +
 | ||||
| +      if (! relocation_in_progress)
 | ||||
| +	{
 | ||||
| +	  /* Notify the debugger that relocations are about to happen.  */
 | ||||
| +	  LIBC_PROBE (rtld-reloc_start, 2, args->nsid, r);
 | ||||
| +	  relocation_in_progress = 1;
 | ||||
| +	}
 | ||||
|  #ifdef SHARED | ||||
| -	  if (__builtin_expect (GLRO(dl_profile) != NULL, 0))
 | ||||
| +      if (__builtin_expect (GLRO(dl_profile) != NULL, 0))
 | ||||
| +	{
 | ||||
| +	  /* If this here is the shared object which we want to profile
 | ||||
| +	     make sure the profile is started.  We can find out whether
 | ||||
| +	     this is necessary or not by observing the `_dl_profile_map'
 | ||||
| +	     variable.  If it was NULL but is not NULL afterwars we must
 | ||||
| +	     start the profiling.  */
 | ||||
| +	  struct link_map *old_profile_map = GL(dl_profile_map);
 | ||||
| +
 | ||||
| +	  _dl_relocate_object (l, l->l_scope, reloc_mode | RTLD_LAZY, 1);
 | ||||
| +
 | ||||
| +	  if (old_profile_map == NULL && GL(dl_profile_map) != NULL)
 | ||||
|  	    { | ||||
| -	      /* If this here is the shared object which we want to profile
 | ||||
| -		 make sure the profile is started.  We can find out whether
 | ||||
| -		 this is necessary or not by observing the `_dl_profile_map'
 | ||||
| -		 variable.  If was NULL but is not NULL afterwars we must
 | ||||
| -		 start the profiling.  */
 | ||||
| -	      struct link_map *old_profile_map = GL(dl_profile_map);
 | ||||
| -
 | ||||
| -	      _dl_relocate_object (l, l->l_scope, reloc_mode | RTLD_LAZY, 1);
 | ||||
| -
 | ||||
| -	      if (old_profile_map == NULL && GL(dl_profile_map) != NULL)
 | ||||
| -		{
 | ||||
| -		  /* We must prepare the profiling.  */
 | ||||
| -		  _dl_start_profile ();
 | ||||
| -
 | ||||
| -		  /* Prevent unloading the object.  */
 | ||||
| -		  GL(dl_profile_map)->l_flags_1 |= DF_1_NODELETE;
 | ||||
| -		}
 | ||||
| +	      /* We must prepare the profiling.  */
 | ||||
| +	      _dl_start_profile ();
 | ||||
| +
 | ||||
| +	      /* Prevent unloading the object.  */
 | ||||
| +	      GL(dl_profile_map)->l_flags_1 |= DF_1_NODELETE;
 | ||||
|  	    } | ||||
| -	  else
 | ||||
| -#endif
 | ||||
| -	    _dl_relocate_object (l, l->l_scope, reloc_mode, 0);
 | ||||
|  	} | ||||
| -
 | ||||
| -      if (l == new)
 | ||||
| -	break;
 | ||||
| -      l = l->l_prev;
 | ||||
| +      else
 | ||||
| +#endif
 | ||||
| +	_dl_relocate_object (l, l->l_scope, reloc_mode, 0);
 | ||||
|      } | ||||
|   | ||||
|    /* If the file is not loaded now as a dependency, add the search | ||||
| diff -Nrup a/elf/tst-relsort1.c b/elf/tst-relsort1.c
 | ||||
| --- a/elf/tst-relsort1.c	1969-12-31 17:00:00.000000000 -0700
 | ||||
| +++ b/elf/tst-relsort1.c	2012-01-29 21:45:18.913344636 -0700
 | ||||
| @@ -0,0 +1,19 @@
 | ||||
| +#include <dlfcn.h>
 | ||||
| +#include <stdio.h>
 | ||||
| +
 | ||||
| +
 | ||||
| +static int
 | ||||
| +do_test ()
 | ||||
| +{
 | ||||
| +  const char lib[] = "$ORIGIN/tst-relsort1mod1.so";
 | ||||
| +  void *h = dlopen (lib, RTLD_NOW);
 | ||||
| +  if (h == NULL)
 | ||||
| +    {
 | ||||
| +      puts (dlerror ());
 | ||||
| +      return 1;
 | ||||
| +    }
 | ||||
| +  return 0;
 | ||||
| +}
 | ||||
| +
 | ||||
| +#define TEST_FUNCTION do_test ()
 | ||||
| +#include "../test-skeleton.c"
 | ||||
| diff -Nrup a/elf/tst-relsort1mod1.c b/elf/tst-relsort1mod1.c
 | ||||
| --- a/elf/tst-relsort1mod1.c	1969-12-31 17:00:00.000000000 -0700
 | ||||
| +++ b/elf/tst-relsort1mod1.c	2012-01-29 21:45:18.914344636 -0700
 | ||||
| @@ -0,0 +1,7 @@
 | ||||
| +extern int foo (double);
 | ||||
| +
 | ||||
| +int
 | ||||
| +bar (void)
 | ||||
| +{
 | ||||
| +  return foo (1.2);
 | ||||
| +}
 | ||||
| diff -Nrup a/elf/tst-relsort1mod2.c b/elf/tst-relsort1mod2.c
 | ||||
| --- a/elf/tst-relsort1mod2.c	1969-12-31 17:00:00.000000000 -0700
 | ||||
| +++ b/elf/tst-relsort1mod2.c	2012-01-29 21:45:18.914344636 -0700
 | ||||
| @@ -0,0 +1,7 @@
 | ||||
| +#include <math.h>
 | ||||
| +
 | ||||
| +int
 | ||||
| +foo (double d)
 | ||||
| +{
 | ||||
| +  return floor (d) != 0.0;
 | ||||
| +}
 | ||||
							
								
								
									
										11
									
								
								glibc.spec
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								glibc.spec
									
									
									
									
									
								
							| @ -28,7 +28,7 @@ | ||||
| Summary: The GNU libc libraries | ||||
| Name: glibc | ||||
| Version: %{glibcversion} | ||||
| Release: 6%{?dist} | ||||
| Release: 7%{?dist} | ||||
| # GPLv2+ is used in a bunch of programs, LGPLv2+ is used for libraries. | ||||
| # Things that are linked directly into dynamically linked programs | ||||
| # and shared libraries (e.g. crt files, lib*_nonshared.a) have an additional | ||||
| @ -63,6 +63,9 @@ Patch11: %{name}-rh622499.patch | ||||
| Patch12: %{name}-rh179072.patch | ||||
| Patch13: %{name}-rh697421.patch | ||||
| Patch14: %{name}-rh740682.patch | ||||
| Patch15: %{name}-sw13618.patch | ||||
| # Fix bogus sorting code which was copied from dl-deps. | ||||
| Patch16: %{name}-sw13618-2.patch | ||||
| 
 | ||||
| Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) | ||||
| Obsoletes: glibc-profile < 2.4 | ||||
| @ -295,6 +298,8 @@ rm -rf %{glibcportsdir} | ||||
| %patch12 -p1 | ||||
| %patch13 -p1 | ||||
| %patch14 -p1 | ||||
| %patch15 -p1 | ||||
| %patch16 -p1 | ||||
| 
 | ||||
| # A lot of programs still misuse memcpy when they have to use | ||||
| # memmove. The memcpy implementation below is not tolerant at | ||||
| @ -1147,6 +1152,10 @@ rm -f *.filelist* | ||||
| %endif | ||||
| 
 | ||||
| %changelog | ||||
| * Sun Jan 29 2012 Jeff Law <law@redhat.com> - 2.15-7 | ||||
|   - Sort objects before relocations (sw#13618) | ||||
|   - Fix bogus sort code that was copied from dl-deps.c. | ||||
| 
 | ||||
| * Thu Jan 26 2012 Jeff Law <law@redhat.com> - 2.15-6 | ||||
|   - First argument to settimeofday can be null (#740682) | ||||
|   - Add aliases for ISO-10646-UCS-2 (#697421) | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user