wok diff glibc/stuff/glibc-2.14.1-sort-1.patch @ rev 12269

Up: glibc (2.14.1)
author Christophe Lincoln <pankso@slitaz.org>
date Thu Apr 12 16:31:36 2012 +0200 (2012-04-12)
parents
children
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/glibc/stuff/glibc-2.14.1-sort-1.patch	Thu Apr 12 16:31:36 2012 +0200
     1.3 @@ -0,0 +1,273 @@
     1.4 +Submitted By:            Bruce Dubbs <bdubbs_at_linuxfromscratch_dot_org>
     1.5 +Date:                    2012-02-24
     1.6 +Initial Package Version: 2.14.1
     1.7 +Upstream Status:         From upstream
     1.8 +Origin:                  Upstream
     1.9 +Description:             Sort objects by dependency before relocation.
    1.10 +                         Fixes segfault in dlopen for several programs.
    1.11 +
    1.12 +diff --git a/Makeconfig b/Makeconfig
    1.13 +index 2db2821..68547b2 100644
    1.14 +--- a/Makeconfig
    1.15 ++++ b/Makeconfig
    1.16 +@@ -938,6 +938,12 @@ libdl =
    1.17 + endif
    1.18 + endif
    1.19 + 
    1.20 ++ifeq ($(build-shared),yes)
    1.21 ++libm = $(common-objpfx)math/libm.so$(libm.so-version)
    1.22 ++else
    1.23 ++libm = $(common-objpfx)math/libm.a
    1.24 ++endif
    1.25 ++
    1.26 + # These are the subdirectories containing the library source.  The order
    1.27 + # is more or less arbitrary.  The sorting step will take care of the
    1.28 + # dependencies.
    1.29 +diff --git a/elf/Makefile b/elf/Makefile
    1.30 +index 052e763..3f1772a 100644
    1.31 +--- a/elf/Makefile
    1.32 ++++ b/elf/Makefile
    1.33 +@@ -124,7 +124,8 @@ distribute	:= rtld-Rules \
    1.34 + 		   tst-initordera1.c tst-initordera2.c tst-initorderb1.c \
    1.35 + 		   tst-initorderb2.c tst-initordera3.c tst-initordera4.c \
    1.36 + 		   tst-initorder.c \
    1.37 +-		   tst-initorder2.c
    1.38 ++		   tst-initorder2.c \
    1.39 ++		   tst-relsort1.c tst-relsort1mod1.c tst-relsort1mod2.c
    1.40 + 
    1.41 + CFLAGS-dl-runtime.c = -fexceptions -fasynchronous-unwind-tables
    1.42 + CFLAGS-dl-lookup.c = -fexceptions -fasynchronous-unwind-tables
    1.43 +@@ -227,7 +228,7 @@ tests += loadtest restest1 preloadtest loadfail multiload origtest resolvfail \
    1.44 + 	 tst-audit1 tst-audit2 \
    1.45 + 	 tst-stackguard1 tst-addr1 tst-thrlock \
    1.46 + 	 tst-unique1 tst-unique2 tst-unique3 tst-unique4 \
    1.47 +-	 tst-initorder tst-initorder2
    1.48 ++	 tst-initorder tst-initorder2 tst-relsort1
    1.49 + #	 reldep9
    1.50 + test-srcs = tst-pathopt
    1.51 + selinux-enabled := $(shell cat /selinux/enforce 2> /dev/null)
    1.52 +@@ -290,7 +291,9 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \
    1.53 + 		tst-initordera1 tst-initorderb1 \
    1.54 + 		tst-initordera2 tst-initorderb2 \
    1.55 + 		tst-initordera3 tst-initordera4 \
    1.56 +-		tst-initorder2a tst-initorder2b tst-initorder2c tst-initorder2d
    1.57 ++		tst-initorder2a tst-initorder2b tst-initorder2c \
    1.58 ++		tst-initorder2d \
    1.59 ++		tst-relsort1mod1 tst-relsort1mod2
    1.60 + ifeq (yes,$(have-initfini-array))
    1.61 + modules-names += tst-array2dep tst-array5dep
    1.62 + endif
    1.63 +@@ -1195,3 +1198,9 @@ CFLAGS-tst-auditmod6b.c += $(AVX-CFLAGS)
    1.64 + CFLAGS-tst-auditmod6c.c += $(AVX-CFLAGS)
    1.65 + CFLAGS-tst-auditmod7b.c += $(AVX-CFLAGS)
    1.66 + endif
    1.67 ++
    1.68 ++$(objpfx)tst-relsort1: $(libdl)
    1.69 ++$(objpfx)tst-relsort1mod1.so: $(libm) $(objpfx)tst-relsort1mod2.so
    1.70 ++$(objpfx)tst-relsort1mod2.so: $(libm)
    1.71 ++$(objpfx)tst-relsort1.out: $(objpfx)tst-relsort1mod1.so \
    1.72 ++			   $(objpfx)tst-relsort1mod2.so
    1.73 +diff --git a/elf/dl-open.c b/elf/dl-open.c
    1.74 +index a0b5c50..a56bdc1 100644
    1.75 +--- a/elf/dl-open.c
    1.76 ++++ b/elf/dl-open.c
    1.77 +@@ -1,5 +1,5 @@
    1.78 + /* Load a shared object at runtime, relocate it, and run its initializer.
    1.79 +-   Copyright (C) 1996-2007, 2009, 2010, 2011 Free Software Foundation, Inc.
    1.80 ++   Copyright (C) 1996-2007, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
    1.81 +    This file is part of the GNU C Library.
    1.82 + 
    1.83 +    The GNU C Library is free software; you can redistribute it and/or
    1.84 +@@ -303,45 +303,109 @@ dl_open_worker (void *a)
    1.85 +   if (GLRO(dl_lazy))
    1.86 +     reloc_mode |= mode & RTLD_LAZY;
    1.87 + 
    1.88 +-  /* Relocate the objects loaded.  We do this in reverse order so that copy
    1.89 +-     relocs of earlier objects overwrite the data written by later objects.  */
    1.90 +-
    1.91 ++  /* Sort the objects by dependency for the relocation process.  This
    1.92 ++     allows IFUNC relocations to work and it also means copy
    1.93 ++     relocation of dependencies are if necessary overwritten.  */
    1.94 ++  size_t nmaps = 0;
    1.95 +   struct link_map *l = new;
    1.96 +-  while (l->l_next)
    1.97 +-    l = l->l_next;
    1.98 +-  while (1)
    1.99 ++  do
   1.100 ++    {
   1.101 ++      if (! l->l_real->l_relocated)
   1.102 ++	++nmaps;
   1.103 ++      l = l->l_next;
   1.104 ++    }
   1.105 ++  while (l != NULL);
   1.106 ++  struct link_map *maps[nmaps];
   1.107 ++  nmaps = 0;
   1.108 ++  l = new;
   1.109 ++  do
   1.110 +     {
   1.111 +       if (! l->l_real->l_relocated)
   1.112 ++	maps[nmaps++] = l;
   1.113 ++      l = l->l_next;
   1.114 ++    }
   1.115 ++  while (l != NULL);
   1.116 ++  if (nmaps > 1)
   1.117 ++    {
   1.118 ++      char seen[nmaps];
   1.119 ++      memset (seen, '\0', nmaps);
   1.120 ++      size_t i = 0;
   1.121 ++      while (1)
   1.122 + 	{
   1.123 +-#ifdef SHARED
   1.124 +-	  if (__builtin_expect (GLRO(dl_profile) != NULL, 0))
   1.125 ++	  ++seen[i];
   1.126 ++	  struct link_map *thisp = maps[i];
   1.127 ++
   1.128 ++	  /* Find the last object in the list for which the current one is
   1.129 ++	     a dependency and move the current object behind the object
   1.130 ++	     with the dependency.  */
   1.131 ++	  size_t k = nmaps - 1;
   1.132 ++	  while (k > i)
   1.133 + 	    {
   1.134 +-	      /* If this here is the shared object which we want to profile
   1.135 +-		 make sure the profile is started.  We can find out whether
   1.136 +-		 this is necessary or not by observing the `_dl_profile_map'
   1.137 +-		 variable.  If was NULL but is not NULL afterwars we must
   1.138 +-		 start the profiling.  */
   1.139 +-	      struct link_map *old_profile_map = GL(dl_profile_map);
   1.140 ++	      struct link_map **runp = maps[k]->l_initfini;
   1.141 ++	      if (runp != NULL)
   1.142 ++		/* Look through the dependencies of the object.  */
   1.143 ++		while (*runp != NULL)
   1.144 ++		  if (__builtin_expect (*runp++ == thisp, 0))
   1.145 ++		    {
   1.146 ++		      /* Move the current object to the back past the last
   1.147 ++			 object with it as the dependency.  */
   1.148 ++		      memmove (&maps[i], &maps[i + 1],
   1.149 ++			       (k - i) * sizeof (maps[0]));
   1.150 ++		      maps[k] = thisp;
   1.151 ++
   1.152 ++		      if (seen[i + 1] > 1)
   1.153 ++			{
   1.154 ++			  ++i;
   1.155 ++			  goto next_clear;
   1.156 ++			}
   1.157 ++
   1.158 ++		      char this_seen = seen[i];
   1.159 ++		      memmove (&seen[i], &seen[i + 1],
   1.160 ++			       (k - i) * sizeof (seen[0]));
   1.161 ++		      seen[k] = this_seen;
   1.162 ++
   1.163 ++		      goto next;
   1.164 ++		    }
   1.165 ++
   1.166 ++	      --k;
   1.167 ++	    }
   1.168 + 
   1.169 +-	      _dl_relocate_object (l, l->l_scope, reloc_mode | RTLD_LAZY, 1);
   1.170 ++	  if (++i == nmaps)
   1.171 ++	    break;
   1.172 ++	next_clear:
   1.173 ++	  memset (&seen[i], 0, (nmaps - i) * sizeof (seen[0]));
   1.174 ++	next:;
   1.175 ++	}
   1.176 ++    }
   1.177 + 
   1.178 +-	      if (old_profile_map == NULL && GL(dl_profile_map) != NULL)
   1.179 +-		{
   1.180 +-		  /* We must prepare the profiling.  */
   1.181 +-		  _dl_start_profile ();
   1.182 ++  for (size_t i = nmaps; i-- > 0; )
   1.183 ++    {
   1.184 ++      l = maps[i];
   1.185 + 
   1.186 +-		  /* Prevent unloading the object.  */
   1.187 +-		  GL(dl_profile_map)->l_flags_1 |= DF_1_NODELETE;
   1.188 +-		}
   1.189 ++#ifdef SHARED
   1.190 ++      if (__builtin_expect (GLRO(dl_profile) != NULL, 0))
   1.191 ++	{
   1.192 ++	  /* If this here is the shared object which we want to profile
   1.193 ++	     make sure the profile is started.  We can find out whether
   1.194 ++	     this is necessary or not by observing the `_dl_profile_map'
   1.195 ++	     variable.  If it was NULL but is not NULL afterwars we must
   1.196 ++	     start the profiling.  */
   1.197 ++	  struct link_map *old_profile_map = GL(dl_profile_map);
   1.198 ++
   1.199 ++	  _dl_relocate_object (l, l->l_scope, reloc_mode | RTLD_LAZY, 1);
   1.200 ++
   1.201 ++	  if (old_profile_map == NULL && GL(dl_profile_map) != NULL)
   1.202 ++	    {
   1.203 ++	      /* We must prepare the profiling.  */
   1.204 ++	      _dl_start_profile ();
   1.205 ++
   1.206 ++	      /* Prevent unloading the object.  */
   1.207 ++	      GL(dl_profile_map)->l_flags_1 |= DF_1_NODELETE;
   1.208 + 	    }
   1.209 +-	  else
   1.210 +-#endif
   1.211 +-	    _dl_relocate_object (l, l->l_scope, reloc_mode, 0);
   1.212 + 	}
   1.213 +-
   1.214 +-      if (l == new)
   1.215 +-	break;
   1.216 +-      l = l->l_prev;
   1.217 ++      else
   1.218 ++#endif
   1.219 ++	_dl_relocate_object (l, l->l_scope, reloc_mode, 0);
   1.220 +     }
   1.221 + 
   1.222 +   /* If the file is not loaded now as a dependency, add the search
   1.223 +diff --git a/elf/tst-relsort1.c b/elf/tst-relsort1.c
   1.224 +new file mode 100644
   1.225 +index 0000000..972100c
   1.226 +--- /dev/null
   1.227 ++++ b/elf/tst-relsort1.c
   1.228 +@@ -0,0 +1,19 @@
   1.229 ++#include <dlfcn.h>
   1.230 ++#include <stdio.h>
   1.231 ++
   1.232 ++
   1.233 ++static int
   1.234 ++do_test ()
   1.235 ++{
   1.236 ++  const char lib[] = "$ORIGIN/tst-relsort1mod1.so";
   1.237 ++  void *h = dlopen (lib, RTLD_NOW);
   1.238 ++  if (h == NULL)
   1.239 ++    {
   1.240 ++      puts (dlerror ());
   1.241 ++      return 1;
   1.242 ++    }
   1.243 ++  return 0;
   1.244 ++}
   1.245 ++
   1.246 ++#define TEST_FUNCTION do_test ()
   1.247 ++#include "../test-skeleton.c"
   1.248 +diff --git a/elf/tst-relsort1mod1.c b/elf/tst-relsort1mod1.c
   1.249 +new file mode 100644
   1.250 +index 0000000..9e4a943
   1.251 +--- /dev/null
   1.252 ++++ b/elf/tst-relsort1mod1.c
   1.253 +@@ -0,0 +1,7 @@
   1.254 ++extern int foo (double);
   1.255 ++
   1.256 ++int
   1.257 ++bar (void)
   1.258 ++{
   1.259 ++  return foo (1.2);
   1.260 ++}
   1.261 +diff --git a/elf/tst-relsort1mod2.c b/elf/tst-relsort1mod2.c
   1.262 +new file mode 100644
   1.263 +index 0000000..a2c3e55
   1.264 +--- /dev/null
   1.265 ++++ b/elf/tst-relsort1mod2.c
   1.266 +@@ -0,0 +1,7 @@
   1.267 ++#include <math.h>
   1.268 ++
   1.269 ++int
   1.270 ++foo (double d)
   1.271 ++{
   1.272 ++  return floor (d) != 0.0;
   1.273 ++}
   1.274 +-- 
   1.275 +1.7.3.4
   1.276 +