]>
Commit | Line | Data |
---|---|---|
160aa9a8 PS |
1 | diff -uNrp glibc-2.14/elf.orig/dl-deps.c glibc-2.14/elf/dl-deps.c |
2 | --- glibc-2.14/elf.orig/dl-deps.c 2011-08-10 22:15:04.000000000 +0200 | |
3 | +++ glibc-2.14/elf/dl-deps.c 2011-08-10 22:16:12.107990316 +0200 | |
4 | @@ -1,5 +1,5 @@ | |
5 | /* Load the dependencies of a mapped object. | |
6 | - Copyright (C) 1996-2003, 2004, 2005, 2006, 2007, 2010, 2011 | |
7 | + Copyright (C) 1996-2003, 2004, 2005, 2006, 2007, 2010 | |
8 | Free Software Foundation, Inc. | |
9 | This file is part of the GNU C Library. | |
10 | ||
11 | @@ -596,7 +596,7 @@ Filters not supported with LD_TRACE_PREL | |
12 | /* Need to allocate new array of relocation dependencies. */ | |
13 | struct link_map_reldeps *l_reldeps; | |
14 | l_reldeps = malloc (sizeof (*l_reldeps) | |
15 | - + map->l_reldepsmax | |
16 | + + map->l_reldepsmax | |
17 | * sizeof (struct link_map *)); | |
18 | if (l_reldeps == NULL) | |
19 | /* Bad luck, keep the reldeps duplicated between | |
20 | @@ -618,66 +618,51 @@ Filters not supported with LD_TRACE_PREL | |
21 | map->l_searchlist.r_list[i]->l_reserved = 0; | |
22 | } | |
23 | ||
24 | - /* Sort the initializer list to take dependencies into account. The binary | |
25 | - itself will always be initialize last. */ | |
26 | + /* Now determine the order in which the initialization has to happen. */ | |
27 | memcpy (l_initfini, map->l_searchlist.r_list, | |
28 | nlist * sizeof (struct link_map *)); | |
29 | - if (__builtin_expect (nlist > 1, 1)) | |
30 | + /* We can skip looking for the binary itself which is at the front | |
31 | + of the search list. Look through the list backward so that circular | |
32 | + dependencies are not changing the order. */ | |
33 | + for (i = 1; i < nlist; ++i) | |
34 | { | |
35 | - /* We can skip looking for the binary itself which is at the front | |
36 | - of the search list. */ | |
37 | - i = 1; | |
38 | - bool seen[nlist]; | |
39 | - memset (seen, false, nlist * sizeof (seen[0])); | |
40 | - while (1) | |
41 | + struct link_map *l = map->l_searchlist.r_list[i]; | |
42 | + unsigned int j; | |
43 | + unsigned int k; | |
44 | + | |
45 | + /* Find the place in the initfini list where the map is currently | |
46 | + located. */ | |
47 | + for (j = 1; l_initfini[j] != l; ++j) | |
48 | + ; | |
49 | + | |
50 | + /* Find all object for which the current one is a dependency and | |
51 | + move the found object (if necessary) in front. */ | |
52 | + for (k = j + 1; k < nlist; ++k) | |
53 | { | |
54 | - /* Keep track of which object we looked at this round. */ | |
55 | - seen[i] = true; | |
56 | - struct link_map *thisp = l_initfini[i]; | |
57 | - | |
58 | - /* Find the last object in the list for which the current one is | |
59 | - a dependency and move the current object behind the object | |
60 | - with the dependency. */ | |
61 | - unsigned int k = nlist - 1; | |
62 | - while (k > i) | |
63 | + struct link_map **runp; | |
64 | + | |
65 | + runp = l_initfini[k]->l_initfini; | |
66 | + if (runp != NULL) | |
67 | { | |
68 | - struct link_map **runp = l_initfini[k]->l_initfini; | |
69 | - if (runp != NULL) | |
70 | - /* Look through the dependencies of the object. */ | |
71 | - while (*runp != NULL) | |
72 | - if (__builtin_expect (*runp++ == thisp, 0)) | |
73 | - { | |
74 | - /* Move the current object to the back past the last | |
75 | - object with it as the dependency. */ | |
76 | - memmove (&l_initfini[i], &l_initfini[i + 1], | |
77 | - (k - i) * sizeof (l_initfini[0])); | |
78 | - l_initfini[k] = thisp; | |
79 | - | |
80 | - if (seen[i + 1]) | |
81 | - { | |
82 | - ++i; | |
83 | - goto next_clear; | |
84 | - } | |
85 | - | |
86 | - memmove (&seen[i], &seen[i + 1], | |
87 | - (k - i) * sizeof (seen[0])); | |
88 | - seen[k] = true; | |
89 | + while (*runp != NULL) | |
90 | + if (__builtin_expect (*runp++ == l, 0)) | |
91 | + { | |
92 | + struct link_map *here = l_initfini[k]; | |
93 | ||
94 | - goto next; | |
95 | - } | |
96 | + /* Move it now. */ | |
97 | + memmove (&l_initfini[j] + 1, &l_initfini[j], | |
98 | + (k - j) * sizeof (struct link_map *)); | |
99 | + l_initfini[j] = here; | |
100 | + | |
101 | + /* Don't insert further matches before the last | |
102 | + entry moved to the front. */ | |
103 | + ++j; | |
104 | ||
105 | - --k; | |
106 | + break; | |
107 | + } | |
108 | } | |
109 | - | |
110 | - if (++i == nlist) | |
111 | - break; | |
112 | - next_clear: | |
113 | - memset (&seen[i], false, (nlist - i) * sizeof (seen[0])); | |
114 | - | |
115 | - next:; | |
116 | } | |
117 | } | |
118 | - | |
119 | /* Terminate the list of dependencies. */ | |
120 | l_initfini[nlist] = NULL; | |
121 | atomic_write_barrier (); | |
122 | diff -uNrp glibc-2.14/elf.orig/dl-fini.c glibc-2.14/elf/dl-fini.c | |
123 | --- glibc-2.14/elf.orig/dl-fini.c 2011-05-31 06:12:33.000000000 +0200 | |
124 | +++ glibc-2.14/elf/dl-fini.c 2011-08-10 22:16:13.564724137 +0200 | |
125 | @@ -1,6 +1,5 @@ | |
126 | /* Call the termination functions of loaded shared objects. | |
127 | - Copyright (C) 1995,96,1998-2002,2004-2005,2009,2011 | |
128 | - Free Software Foundation, Inc. | |
129 | + Copyright (C) 1995,96,1998-2002,2004-2005,2009 Free Software Foundation, Inc. | |
130 | This file is part of the GNU C Library. | |
131 | ||
132 | The GNU C Library is free software; you can redistribute it and/or | |
133 | @@ -33,87 +32,86 @@ internal_function | |
134 | _dl_sort_fini (struct link_map *l, struct link_map **maps, size_t nmaps, | |
135 | char *used, Lmid_t ns) | |
136 | { | |
137 | - /* A list of one element need not be sorted. */ | |
138 | - if (nmaps == 1) | |
139 | - return; | |
140 | - | |
141 | - /* We can skip looking for the binary itself which is at the front | |
142 | - of the search list for the main namespace. */ | |
143 | - unsigned int i = ns == LM_ID_BASE; | |
144 | - bool seen[nmaps]; | |
145 | - memset (seen, false, nmaps * sizeof (seen[0])); | |
146 | - while (1) | |
147 | - { | |
148 | - /* Keep track of which object we looked at this round. */ | |
149 | - seen[i] = true; | |
150 | - struct link_map *thisp = maps[i]; | |
151 | - | |
152 | - /* Do not handle ld.so in secondary namespaces and object which | |
153 | - are not removed. */ | |
154 | - if (thisp != thisp->l_real || thisp->l_idx == -1) | |
155 | - goto skip; | |
156 | - | |
157 | - /* Find the last object in the list for which the current one is | |
158 | - a dependency and move the current object behind the object | |
159 | - with the dependency. */ | |
160 | - unsigned int k = nmaps - 1; | |
161 | - while (k > i) | |
162 | - { | |
163 | - struct link_map **runp = maps[k]->l_initfini; | |
164 | - if (runp != NULL) | |
165 | - /* Look through the dependencies of the object. */ | |
166 | - while (*runp != NULL) | |
167 | - if (__builtin_expect (*runp++ == thisp, 0)) | |
168 | - { | |
169 | - move: | |
170 | - /* Move the current object to the back past the last | |
171 | - object with it as the dependency. */ | |
172 | - memmove (&maps[i], &maps[i + 1], | |
173 | - (k - i) * sizeof (maps[0])); | |
174 | - maps[k] = thisp; | |
175 | - | |
176 | - if (used != NULL) | |
177 | + if (ns == LM_ID_BASE) | |
178 | + /* The main executable always comes first. */ | |
179 | + l = l->l_next; | |
180 | + | |
181 | + for (; l != NULL; l = l->l_next) | |
182 | + /* Do not handle ld.so in secondary namespaces and object which | |
183 | + are not removed. */ | |
184 | + if (l == l->l_real && l->l_idx != -1) | |
185 | + { | |
186 | + /* Find the place in the 'maps' array. */ | |
187 | + unsigned int j; | |
188 | + for (j = ns == LM_ID_BASE ? 1 : 0; maps[j] != l; ++j) | |
189 | + assert (j < nmaps); | |
190 | + | |
191 | + /* Find all object for which the current one is a dependency | |
192 | + and move the found object (if necessary) in front. */ | |
193 | + for (unsigned int k = j + 1; k < nmaps; ++k) | |
194 | + { | |
195 | + struct link_map **runp = maps[k]->l_initfini; | |
196 | + if (runp != NULL) | |
197 | + { | |
198 | + while (*runp != NULL) | |
199 | + if (*runp == l) | |
200 | { | |
201 | - char here_used = used[i]; | |
202 | - memmove (&used[i], &used[i + 1], | |
203 | - (k - i) * sizeof (used[0])); | |
204 | - used[k] = here_used; | |
205 | - } | |
206 | + struct link_map *here = maps[k]; | |
207 | ||
208 | - if (seen[i + 1]) | |
209 | - { | |
210 | - ++i; | |
211 | - goto next_clear; | |
212 | - } | |
213 | + /* Move it now. */ | |
214 | + memmove (&maps[j] + 1, | |
215 | + &maps[j], (k - j) * sizeof (struct link_map *)); | |
216 | + maps[j] = here; | |
217 | ||
218 | - memmove (&seen[i], &seen[i + 1], (k - i) * sizeof (seen[0])); | |
219 | - seen[k] = true; | |
220 | + if (used != NULL) | |
221 | + { | |
222 | + char here_used = used[k]; | |
223 | ||
224 | - goto next; | |
225 | - } | |
226 | + memmove (&used[j] + 1, | |
227 | + &used[j], (k - j) * sizeof (char)); | |
228 | + used[j] = here_used; | |
229 | + } | |
230 | ||
231 | - if (__builtin_expect (maps[k]->l_reldeps != NULL, 0)) | |
232 | - { | |
233 | - unsigned int m = maps[k]->l_reldeps->act; | |
234 | - struct link_map **relmaps = &maps[k]->l_reldeps->list[0]; | |
235 | + ++j; | |
236 | ||
237 | - /* Look through the relocation dependencies of the object. */ | |
238 | - while (m-- > 0) | |
239 | - if (__builtin_expect (relmaps[m] == thisp, 0)) | |
240 | - goto move; | |
241 | - } | |
242 | - | |
243 | - --k; | |
244 | - } | |
245 | - | |
246 | - skip: | |
247 | - if (++i == nmaps) | |
248 | - break; | |
249 | - next_clear: | |
250 | - memset (&seen[i], false, (nmaps - i) * sizeof (seen[0])); | |
251 | - | |
252 | - next:; | |
253 | - } | |
254 | + break; | |
255 | + } | |
256 | + else | |
257 | + ++runp; | |
258 | + } | |
259 | + | |
260 | + if (__builtin_expect (maps[k]->l_reldeps != NULL, 0)) | |
261 | + { | |
262 | + unsigned int m = maps[k]->l_reldeps->act; | |
263 | + struct link_map **relmaps = &maps[k]->l_reldeps->list[0]; | |
264 | + | |
265 | + while (m-- > 0) | |
266 | + { | |
267 | + if (relmaps[m] == l) | |
268 | + { | |
269 | + struct link_map *here = maps[k]; | |
270 | + | |
271 | + /* Move it now. */ | |
272 | + memmove (&maps[j] + 1, | |
273 | + &maps[j], | |
274 | + (k - j) * sizeof (struct link_map *)); | |
275 | + maps[j] = here; | |
276 | + | |
277 | + if (used != NULL) | |
278 | + { | |
279 | + char here_used = used[k]; | |
280 | + | |
281 | + memmove (&used[j] + 1, | |
282 | + &used[j], (k - j) * sizeof (char)); | |
283 | + used[j] = here_used; | |
284 | + } | |
285 | + | |
286 | + break; | |
287 | + } | |
288 | + } | |
289 | + } | |
290 | + } | |
291 | + } | |
292 | } | |
293 | ||
294 | ||
295 | @@ -198,8 +196,9 @@ _dl_fini (void) | |
296 | assert (ns == LM_ID_BASE || i == nloaded || i == nloaded - 1); | |
297 | nmaps = i; | |
298 | ||
299 | - /* Now we have to do the sorting. */ | |
300 | - _dl_sort_fini (GL(dl_ns)[ns]._ns_loaded, maps, nmaps, NULL, ns); | |
301 | + if (nmaps != 0) | |
302 | + /* Now we have to do the sorting. */ | |
303 | + _dl_sort_fini (GL(dl_ns)[ns]._ns_loaded, maps, nmaps, NULL, ns); | |
304 | ||
305 | /* We do not rely on the linked list of loaded object anymore from | |
306 | this point on. We have our own list here (maps). The various | |
307 | diff -uNrp glibc-2.14/elf.orig/Makefile glibc-2.14/elf/Makefile | |
308 | --- glibc-2.14/elf.orig/Makefile 2011-05-31 06:12:33.000000000 +0200 | |
309 | +++ glibc-2.14/elf/Makefile 2011-08-10 22:16:11.447959889 +0200 | |
310 | @@ -119,10 +119,7 @@ distribute := rtld-Rules \ | |
311 | ifuncmain7.c ifuncmain7pic.c ifuncmain7picstatic.c \ | |
312 | ifuncmain7pie.c ifuncmain7static.c \ | |
313 | tst-unique1.c tst-unique1mod1.c tst-unique1mod2.c \ | |
314 | - tst-unique2.c tst-unique2mod1.c tst-unique2mod2.c \ | |
315 | - tst-initordera1.c tst-initordera2.c tst-initorderb1.c \ | |
316 | - tst-initorderb2.c tst-initordera3.c tst-initordera4.c \ | |
317 | - tst-initorder.c | |
318 | + tst-unique2.c tst-unique2mod1.c tst-unique2mod2.c | |
319 | ||
320 | CFLAGS-dl-runtime.c = -fexceptions -fasynchronous-unwind-tables | |
321 | CFLAGS-dl-lookup.c = -fexceptions -fasynchronous-unwind-tables | |
322 | @@ -224,8 +221,7 @@ tests += loadtest restest1 preloadtest l | |
323 | unload3 unload4 unload5 unload6 unload7 tst-global1 order2 \ | |
324 | tst-audit1 tst-audit2 \ | |
325 | tst-stackguard1 tst-addr1 tst-thrlock \ | |
326 | - tst-unique1 tst-unique2 tst-unique3 tst-unique4 \ | |
327 | - tst-initorder | |
328 | + tst-unique1 tst-unique2 tst-unique3 tst-unique4 | |
329 | # reldep9 | |
330 | test-srcs = tst-pathopt | |
331 | selinux-enabled := $(shell cat /selinux/enforce 2> /dev/null) | |
332 | @@ -283,10 +279,7 @@ modules-names = testobj1 testobj2 testob | |
333 | tst-unique1mod1 tst-unique1mod2 \ | |
334 | tst-unique2mod1 tst-unique2mod2 \ | |
335 | tst-unique3lib tst-unique3lib2 \ | |
336 | - tst-unique4lib \ | |
337 | - tst-initordera1 tst-initorderb1 \ | |
338 | - tst-initordera2 tst-initorderb2 \ | |
339 | - tst-initordera3 tst-initordera4 | |
340 | + tst-unique4lib | |
341 | ifeq (yes,$(have-initfini-array)) | |
342 | modules-names += tst-array2dep tst-array5dep | |
343 | endif | |
344 | @@ -568,11 +561,6 @@ $(objpfx)unload6mod2.so: $(libdl) | |
345 | $(objpfx)unload6mod3.so: $(libdl) | |
346 | $(objpfx)unload7mod1.so: $(libdl) | |
347 | $(objpfx)unload7mod2.so: $(objpfx)unload7mod1.so | |
348 | -$(objpfx)tst-initordera2.so: $(objpfx)tst-initordera1.so | |
349 | -$(objpfx)tst-initorderb2.so: $(objpfx)tst-initorderb1.so $(objpfx)tst-initordera2.so | |
350 | -$(objpfx)tst-initordera3.so: $(objpfx)tst-initorderb2.so $(objpfx)tst-initorderb1.so | |
351 | -$(objpfx)tst-initordera4.so: $(objpfx)tst-initordera3.so | |
352 | -$(objpfx)tst-initorder: $(objpfx)tst-initordera4.so $(objpfx)tst-initordera1.so $(objpfx)tst-initorderb2.so | |
353 | ||
354 | LDFLAGS-tst-tlsmod5.so = -nostdlib | |
355 | LDFLAGS-tst-tlsmod6.so = -nostdlib | |
356 | @@ -1150,12 +1138,6 @@ $(objpfx)tst-unique3.out: $(objpfx)tst-u | |
357 | ||
358 | $(objpfx)tst-unique4: $(objpfx)tst-unique4lib.so | |
359 | ||
360 | -$(objpfx)tst-initorder.out: $(objpfx)tst-initorder | |
361 | - $(elf-objpfx)${rtld-installed-name} \ | |
362 | - --library-path $(rpath-link)$(patsubst %,:%,$(sysdep-library-path)) \ | |
363 | - $< > $@ | |
364 | - cmp $@ tst-initorder.exp > /dev/null | |
365 | - | |
366 | ifeq (yes,$(config-cflags-avx)) | |
367 | AVX-CFLAGS=-mavx | |
368 | ifeq (yes,$(config-cflags-novzeroupper)) |