wok-current diff glibc/stuff/glibc-2.14.1-sort-1.patch @ rev 19902
Up: db (6.2.23)
author | Alexander Medvedev <devl547@gmail.com> |
---|---|
date | Sat Apr 08 22:00:16 2017 +0000 (2017-04-08) |
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 Sat Apr 08 22:00:16 2017 +0000 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 +