Annotation of /trunk/glibc/patches/glibc-2.15-ifunc.patch
Parent Directory | Revision Log
Revision 1806 -
(hide annotations)
(download)
Tue Jun 12 12:33:27 2012 UTC (12 years, 3 months ago) by niro
File size: 7640 byte(s)
Tue Jun 12 12:33:27 2012 UTC (12 years, 3 months ago) by niro
File size: 7640 byte(s)
-added patches for 2.15-r1
1 | niro | 1806 | diff --git a/Makeconfig b/Makeconfig |
2 | index 2db2821..68547b2 100644 | ||
3 | --- a/Makeconfig | ||
4 | +++ b/Makeconfig | ||
5 | @@ -900,6 +900,12 @@ else | ||
6 | libdl = $(common-objpfx)dlfcn/libdl.a | ||
7 | endif | ||
8 | |||
9 | +ifeq ($(build-shared),yes) | ||
10 | +libm = $(common-objpfx)math/libm.so$(libm.so-version) | ||
11 | +else | ||
12 | +libm = $(common-objpfx)math/libm.a | ||
13 | +endif | ||
14 | + | ||
15 | # These are the subdirectories containing the library source. The order | ||
16 | # is more or less arbitrary. The sorting step will take care of the | ||
17 | # dependencies. | ||
18 | diff --git a/elf/Makefile b/elf/Makefile | ||
19 | index 052e763..3f1772a 100644 | ||
20 | --- a/elf/Makefile | ||
21 | +++ b/elf/Makefile | ||
22 | @@ -124,7 +124,8 @@ distribute := rtld-Rules \ | ||
23 | tst-initordera1.c tst-initordera2.c tst-initorderb1.c \ | ||
24 | tst-initorderb2.c tst-initordera3.c tst-initordera4.c \ | ||
25 | tst-initorder.c \ | ||
26 | - tst-initorder2.c | ||
27 | + tst-initorder2.c \ | ||
28 | + tst-relsort1.c tst-relsort1mod1.c tst-relsort1mod2.c | ||
29 | |||
30 | CFLAGS-dl-runtime.c = -fexceptions -fasynchronous-unwind-tables | ||
31 | CFLAGS-dl-lookup.c = -fexceptions -fasynchronous-unwind-tables | ||
32 | @@ -227,7 +228,7 @@ tests += loadtest restest1 preloadtest loadfail multiload origtest resolvfail \ | ||
33 | tst-audit1 tst-audit2 \ | ||
34 | tst-stackguard1 tst-addr1 tst-thrlock \ | ||
35 | tst-unique1 tst-unique2 tst-unique3 tst-unique4 \ | ||
36 | - tst-initorder tst-initorder2 | ||
37 | + tst-initorder tst-initorder2 tst-relsort1 | ||
38 | # reldep9 | ||
39 | test-srcs = tst-pathopt | ||
40 | selinux-enabled := $(shell cat /selinux/enforce 2> /dev/null) | ||
41 | @@ -290,7 +291,9 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \ | ||
42 | tst-initordera1 tst-initorderb1 \ | ||
43 | tst-initordera2 tst-initorderb2 \ | ||
44 | tst-initordera3 tst-initordera4 \ | ||
45 | - tst-initorder2a tst-initorder2b tst-initorder2c tst-initorder2d | ||
46 | + tst-initorder2a tst-initorder2b tst-initorder2c \ | ||
47 | + tst-initorder2d \ | ||
48 | + tst-relsort1mod1 tst-relsort1mod2 | ||
49 | ifeq (yes,$(have-initfini-array)) | ||
50 | modules-names += tst-array2dep tst-array5dep | ||
51 | endif | ||
52 | @@ -1195,3 +1198,9 @@ CFLAGS-tst-auditmod6b.c += $(AVX-CFLAGS) | ||
53 | CFLAGS-tst-auditmod6c.c += $(AVX-CFLAGS) | ||
54 | CFLAGS-tst-auditmod7b.c += $(AVX-CFLAGS) | ||
55 | endif | ||
56 | + | ||
57 | +$(objpfx)tst-relsort1: $(libdl) | ||
58 | +$(objpfx)tst-relsort1mod1.so: $(libm) $(objpfx)tst-relsort1mod2.so | ||
59 | +$(objpfx)tst-relsort1mod2.so: $(libm) | ||
60 | +$(objpfx)tst-relsort1.out: $(objpfx)tst-relsort1mod1.so \ | ||
61 | + $(objpfx)tst-relsort1mod2.so | ||
62 | diff --git a/elf/dl-open.c b/elf/dl-open.c | ||
63 | index a0b5c50..a56bdc1 100644 | ||
64 | --- a/elf/dl-open.c | ||
65 | +++ b/elf/dl-open.c | ||
66 | @@ -1,5 +1,5 @@ | ||
67 | /* Load a shared object at runtime, relocate it, and run its initializer. | ||
68 | - Copyright (C) 1996-2007, 2009, 2010, 2011 Free Software Foundation, Inc. | ||
69 | + Copyright (C) 1996-2007, 2009, 2010, 2011, 2012 Free Software Foundation, Inc. | ||
70 | This file is part of the GNU C Library. | ||
71 | |||
72 | The GNU C Library is free software; you can redistribute it and/or | ||
73 | @@ -302,45 +302,109 @@ dl_open_worker (void *a) | ||
74 | if (GLRO(dl_lazy)) | ||
75 | reloc_mode |= mode & RTLD_LAZY; | ||
76 | |||
77 | - /* Relocate the objects loaded. We do this in reverse order so that copy | ||
78 | - relocs of earlier objects overwrite the data written by later objects. */ | ||
79 | - | ||
80 | + /* Sort the objects by dependency for the relocation process. This | ||
81 | + allows IFUNC relocations to work and it also means copy | ||
82 | + relocation of dependencies are if necessary overwritten. */ | ||
83 | + size_t nmaps = 0; | ||
84 | struct link_map *l = new; | ||
85 | - while (l->l_next) | ||
86 | - l = l->l_next; | ||
87 | - while (1) | ||
88 | + do | ||
89 | + { | ||
90 | + if (! l->l_real->l_relocated) | ||
91 | + ++nmaps; | ||
92 | + l = l->l_next; | ||
93 | + } | ||
94 | + while (l != NULL); | ||
95 | + struct link_map *maps[nmaps]; | ||
96 | + nmaps = 0; | ||
97 | + l = new; | ||
98 | + do | ||
99 | { | ||
100 | if (! l->l_real->l_relocated) | ||
101 | + maps[nmaps++] = l; | ||
102 | + l = l->l_next; | ||
103 | + } | ||
104 | + while (l != NULL); | ||
105 | + if (nmaps > 1) | ||
106 | + { | ||
107 | + char seen[nmaps]; | ||
108 | + memset (seen, '\0', nmaps); | ||
109 | + size_t i = 0; | ||
110 | + while (1) | ||
111 | { | ||
112 | -#ifdef SHARED | ||
113 | - if (__builtin_expect (GLRO(dl_profile) != NULL, 0)) | ||
114 | + ++seen[i]; | ||
115 | + struct link_map *thisp = maps[i]; | ||
116 | + | ||
117 | + /* Find the last object in the list for which the current one is | ||
118 | + a dependency and move the current object behind the object | ||
119 | + with the dependency. */ | ||
120 | + size_t k = nmaps - 1; | ||
121 | + while (k > i) | ||
122 | { | ||
123 | - /* If this here is the shared object which we want to profile | ||
124 | - make sure the profile is started. We can find out whether | ||
125 | - this is necessary or not by observing the `_dl_profile_map' | ||
126 | - variable. If was NULL but is not NULL afterwars we must | ||
127 | - start the profiling. */ | ||
128 | - struct link_map *old_profile_map = GL(dl_profile_map); | ||
129 | + struct link_map **runp = maps[k]->l_initfini; | ||
130 | + if (runp != NULL) | ||
131 | + /* Look through the dependencies of the object. */ | ||
132 | + while (*runp != NULL) | ||
133 | + if (__builtin_expect (*runp++ == thisp, 0)) | ||
134 | + { | ||
135 | + /* Move the current object to the back past the last | ||
136 | + object with it as the dependency. */ | ||
137 | + memmove (&maps[i], &maps[i + 1], | ||
138 | + (k - i) * sizeof (maps[0])); | ||
139 | + maps[k] = thisp; | ||
140 | + | ||
141 | + if (seen[i + 1] > 1) | ||
142 | + { | ||
143 | + ++i; | ||
144 | + goto next_clear; | ||
145 | + } | ||
146 | + | ||
147 | + char this_seen = seen[i]; | ||
148 | + memmove (&seen[i], &seen[i + 1], | ||
149 | + (k - i) * sizeof (seen[0])); | ||
150 | + seen[k] = this_seen; | ||
151 | + | ||
152 | + goto next; | ||
153 | + } | ||
154 | + | ||
155 | + --k; | ||
156 | + } | ||
157 | |||
158 | - _dl_relocate_object (l, l->l_scope, reloc_mode | RTLD_LAZY, 1); | ||
159 | + if (++i == nmaps) | ||
160 | + break; | ||
161 | + next_clear: | ||
162 | + memset (&seen[i], 0, (nmaps - i) * sizeof (seen[0])); | ||
163 | + next:; | ||
164 | + } | ||
165 | + } | ||
166 | |||
167 | - if (old_profile_map == NULL && GL(dl_profile_map) != NULL) | ||
168 | - { | ||
169 | - /* We must prepare the profiling. */ | ||
170 | - _dl_start_profile (); | ||
171 | + for (size_t i = nmaps; i-- > 0; ) | ||
172 | + { | ||
173 | + l = maps[i]; | ||
174 | |||
175 | - /* Prevent unloading the object. */ | ||
176 | - GL(dl_profile_map)->l_flags_1 |= DF_1_NODELETE; | ||
177 | - } | ||
178 | +#ifdef SHARED | ||
179 | + if (__builtin_expect (GLRO(dl_profile) != NULL, 0)) | ||
180 | + { | ||
181 | + /* If this here is the shared object which we want to profile | ||
182 | + make sure the profile is started. We can find out whether | ||
183 | + this is necessary or not by observing the `_dl_profile_map' | ||
184 | + variable. If it was NULL but is not NULL afterwars we must | ||
185 | + start the profiling. */ | ||
186 | + struct link_map *old_profile_map = GL(dl_profile_map); | ||
187 | + | ||
188 | + _dl_relocate_object (l, l->l_scope, reloc_mode | RTLD_LAZY, 1); | ||
189 | + | ||
190 | + if (old_profile_map == NULL && GL(dl_profile_map) != NULL) | ||
191 | + { | ||
192 | + /* We must prepare the profiling. */ | ||
193 | + _dl_start_profile (); | ||
194 | + | ||
195 | + /* Prevent unloading the object. */ | ||
196 | + GL(dl_profile_map)->l_flags_1 |= DF_1_NODELETE; | ||
197 | } | ||
198 | - else | ||
199 | -#endif | ||
200 | - _dl_relocate_object (l, l->l_scope, reloc_mode, 0); | ||
201 | } | ||
202 | - | ||
203 | - if (l == new) | ||
204 | - break; | ||
205 | - l = l->l_prev; | ||
206 | + else | ||
207 | +#endif | ||
208 | + _dl_relocate_object (l, l->l_scope, reloc_mode, 0); | ||
209 | } | ||
210 | |||
211 | /* If the file is not loaded now as a dependency, add the search | ||
212 | diff --git a/elf/tst-relsort1.c b/elf/tst-relsort1.c | ||
213 | new file mode 100644 | ||
214 | index 0000000..972100c | ||
215 | --- /dev/null | ||
216 | +++ b/elf/tst-relsort1.c | ||
217 | @@ -0,0 +1,19 @@ | ||
218 | +#include <dlfcn.h> | ||
219 | +#include <stdio.h> | ||
220 | + | ||
221 | + | ||
222 | +static int | ||
223 | +do_test () | ||
224 | +{ | ||
225 | + const char lib[] = "$ORIGIN/tst-relsort1mod1.so"; | ||
226 | + void *h = dlopen (lib, RTLD_NOW); | ||
227 | + if (h == NULL) | ||
228 | + { | ||
229 | + puts (dlerror ()); | ||
230 | + return 1; | ||
231 | + } | ||
232 | + return 0; | ||
233 | +} | ||
234 | + | ||
235 | +#define TEST_FUNCTION do_test () | ||
236 | +#include "../test-skeleton.c" | ||
237 | diff --git a/elf/tst-relsort1mod1.c b/elf/tst-relsort1mod1.c | ||
238 | new file mode 100644 | ||
239 | index 0000000..9e4a943 | ||
240 | --- /dev/null | ||
241 | +++ b/elf/tst-relsort1mod1.c | ||
242 | @@ -0,0 +1,7 @@ | ||
243 | +extern int foo (double); | ||
244 | + | ||
245 | +int | ||
246 | +bar (void) | ||
247 | +{ | ||
248 | + return foo (1.2); | ||
249 | +} | ||
250 | diff --git a/elf/tst-relsort1mod2.c b/elf/tst-relsort1mod2.c | ||
251 | new file mode 100644 | ||
252 | index 0000000..a2c3e55 | ||
253 | --- /dev/null | ||
254 | +++ b/elf/tst-relsort1mod2.c | ||
255 | @@ -0,0 +1,7 @@ | ||
256 | +#include <math.h> | ||
257 | + | ||
258 | +int | ||
259 | +foo (double d) | ||
260 | +{ | ||
261 | + return floor (d) != 0.0; | ||
262 | +} |