1 |
vapier 11/05/28 18:44:57 |
2 |
|
3 |
Modified: README.history |
4 |
Added: 0043_all_glibc-2.12-broken-tls-init.patch |
5 |
Log: |
6 |
add tls init fix from upstream #353224 |
7 |
|
8 |
Revision Changes Path |
9 |
1.19 src/patchsets/glibc/2.13/README.history |
10 |
|
11 |
file : http://sources.gentoo.org/viewvc.cgi/gentoo/src/patchsets/glibc/2.13/README.history?rev=1.19&view=markup |
12 |
plain: http://sources.gentoo.org/viewvc.cgi/gentoo/src/patchsets/glibc/2.13/README.history?rev=1.19&content-type=text/plain |
13 |
diff : http://sources.gentoo.org/viewvc.cgi/gentoo/src/patchsets/glibc/2.13/README.history?r1=1.18&r2=1.19 |
14 |
|
15 |
Index: README.history |
16 |
=================================================================== |
17 |
RCS file: /var/cvsroot/gentoo/src/patchsets/glibc/2.13/README.history,v |
18 |
retrieving revision 1.18 |
19 |
retrieving revision 1.19 |
20 |
diff -u -r1.18 -r1.19 |
21 |
--- README.history 10 Apr 2011 16:13:59 -0000 1.18 |
22 |
+++ README.history 28 May 2011 18:44:57 -0000 1.19 |
23 |
@@ -1,3 +1,6 @@ |
24 |
+7 [pending] |
25 |
+ + 0043_all_glibc-2.12-broken-tls-init.patch |
26 |
+ |
27 |
6 10.04.2011 |
28 |
+ 1508_all_glibc-2.13-hppa-DEFAULT_STACK_PERMS.patch |
29 |
|
30 |
|
31 |
|
32 |
|
33 |
1.1 src/patchsets/glibc/2.13/0043_all_glibc-2.12-broken-tls-init.patch |
34 |
|
35 |
file : http://sources.gentoo.org/viewvc.cgi/gentoo/src/patchsets/glibc/2.13/0043_all_glibc-2.12-broken-tls-init.patch?rev=1.1&view=markup |
36 |
plain: http://sources.gentoo.org/viewvc.cgi/gentoo/src/patchsets/glibc/2.13/0043_all_glibc-2.12-broken-tls-init.patch?rev=1.1&content-type=text/plain |
37 |
|
38 |
Index: 0043_all_glibc-2.12-broken-tls-init.patch |
39 |
=================================================================== |
40 |
https://bugs.gentoo.org/353224 |
41 |
http://sources.redhat.com/bugzilla/show_bug.cgi?id=12453 |
42 |
|
43 |
From d26dfc60edc8c6dd160eefff16a734152a835ca0 Mon Sep 17 00:00:00 2001 |
44 |
From: Martin von Gagern <Martin.vGagern@×××.net> |
45 |
Date: Sat, 14 May 2011 21:25:43 -0400 |
46 |
Subject: [PATCH] Fix handling of static TLS in dlopen'ed objects |
47 |
|
48 |
When dynamically loading a library along with several dependencies, calls to |
49 |
_dl_add_to_slotinfo and _dl_update_slotinfo can become intermixed. As a |
50 |
consequence, _dl_update_slotinfo will update the generation counter of the dtv |
51 |
although not all of the slots belonging to that generation have been added. |
52 |
Subsequent calls to _dl_add_to_slotinfo will add more slots to the same |
53 |
generation, for which no storage will be allocated, as the dtv generation |
54 |
checks will claim no work is necessary. This will lead to uninitialized dtv |
55 |
entries and will likely cause a SIGSEGV when thread local variables are |
56 |
accessed. |
57 |
--- |
58 |
ChangeLog | 10 ++++++++ |
59 |
NEWS | 8 +++--- |
60 |
elf/Makefile | 9 ++++++- |
61 |
elf/dl-open.c | 64 +++++++++++++++++++++++++++++++-------------------- |
62 |
elf/tst-tls19.c | 27 +++++++++++++++++++++ |
63 |
elf/tst-tls19mod1.c | 15 ++++++++++++ |
64 |
elf/tst-tls19mod2.c | 13 ++++++++++ |
65 |
elf/tst-tls19mod3.c | 16 ++++++++++++ |
66 |
8 files changed, 132 insertions(+), 30 deletions(-) |
67 |
create mode 100644 elf/tst-tls19.c |
68 |
create mode 100644 elf/tst-tls19mod1.c |
69 |
create mode 100644 elf/tst-tls19mod2.c |
70 |
create mode 100644 elf/tst-tls19mod3.c |
71 |
|
72 |
2011-05-14 Ulrich Drepper <drepper@×××××.com> |
73 |
|
74 |
[BZ #12453] |
75 |
* elf/dl-open.c (dl_open_worker): Delay calls to _dl_update_slotinfo |
76 |
until all modules are registered in the DTV. |
77 |
* elf/Makefile: Add rules to build and run tst-tls19. |
78 |
* elf/tst-tls19.c: New file. |
79 |
* elf/tst-tls19mod1.c: New file. |
80 |
* elf/tst-tls19mod2.c: New file. |
81 |
* elf/tst-tls19mod3.c: New file. |
82 |
Patch mostly by Martin von Gagern <Martin.vGagern@×××.net>. |
83 |
|
84 |
diff --git a/elf/Makefile b/elf/Makefile |
85 |
index 8d9657d..6efb86c 100644 |
86 |
--- a/elf/Makefile |
87 |
+++ b/elf/Makefile |
88 |
@@ -76,6 +76,7 @@ distribute := rtld-Rules \ |
89 |
tst-tlsmod12.c tst-tls10.h tst-alignmod.c tst-alignmod2.c \ |
90 |
circlemod1.c circlemod1a.c circlemod2.c circlemod2a.c \ |
91 |
circlemod3.c circlemod3a.c nodlopenmod2.c \ |
92 |
+ tst-tls19mod1.c tst-tls19mod2.c tst-tls19mod3.c \ |
93 |
tls-macros.h \ |
94 |
reldep8mod1.c reldep8mod2.c reldep8mod3.c \ |
95 |
nodel2mod1.c nodel2mod2.c nodel2mod3.c \ |
96 |
@@ -194,7 +195,7 @@ tests += loadtest restest1 preloadtest loadfail multiload origtest resolvfail \ |
97 |
restest2 next dblload dblunload reldep5 reldep6 reldep7 reldep8 \ |
98 |
circleload1 tst-tls3 tst-tls4 tst-tls5 tst-tls6 tst-tls7 tst-tls8 \ |
99 |
tst-tls10 tst-tls11 tst-tls12 tst-tls13 tst-tls14 tst-tls15 \ |
100 |
- tst-tls16 tst-tls17 tst-tls18 tst-tls-dlinfo \ |
101 |
+ tst-tls16 tst-tls17 tst-tls18 tst-tls19 tst-tls-dlinfo \ |
102 |
tst-align tst-align2 $(tests-execstack-$(have-z-execstack)) \ |
103 |
tst-dlmodcount tst-dlopenrpath tst-deep1 \ |
104 |
tst-dlmopen1 tst-dlmopen2 tst-dlmopen3 \ |
105 |
@@ -240,6 +241,7 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \ |
106 |
tst-tlsmod13 tst-tlsmod13a tst-tlsmod14a tst-tlsmod14b \ |
107 |
tst-tlsmod15a tst-tlsmod15b tst-tlsmod16a tst-tlsmod16b \ |
108 |
$(tlsmod17a-modules) tst-tlsmod17b $(tlsmod18a-modules) \ |
109 |
+ tst-tls19mod1 tst-tls19mod2 tst-tls19mod3 \ |
110 |
circlemod1 circlemod1a circlemod2 circlemod2a \ |
111 |
circlemod3 circlemod3a \ |
112 |
reldep8mod1 reldep8mod2 reldep8mod3 \ |
113 |
@@ -525,6 +527,8 @@ $(objpfx)tst-tlsmod13a.so: $(objpfx)tst-tlsmod13.so |
114 |
# For tst-tls9-static, make sure the modules it dlopens have libc.so in DT_NEEDED |
115 |
$(objpfx)tst-tlsmod5.so: $(common-objpfx)libc.so |
116 |
$(objpfx)tst-tlsmod6.so: $(common-objpfx)libc.so |
117 |
+$(objpfx)tst-tls19mod1.so: $(objpfx)tst-tls19mod2.so $(objpfx)tst-tls19mod3.so |
118 |
+$(objpfx)tst-tls19mod3.so: $(objpfx)ld.so |
119 |
$(objpfx)reldep8mod3.so: $(objpfx)reldep8mod1.so $(objpfx)reldep8mod2.so |
120 |
$(objpfx)nodel2mod3.so: $(objpfx)nodel2mod1.so $(objpfx)nodel2mod2.so |
121 |
$(objpfx)reldep9mod2.so: $(objpfx)reldep9mod1.so |
122 |
@@ -822,6 +826,9 @@ $(patsubst %,$(objpfx)%.os,$(tlsmod18a-modules)): $(objpfx)tst-tlsmod18a%.os : t |
123 |
$(compile-command.c) -DN=$* |
124 |
$(patsubst %,$(objpfx)%.so,$(tlsmod18a-modules)): $(objpfx)tst-tlsmod18a%.so: $(objpfx)ld.so |
125 |
|
126 |
+$(objpfx)tst-tls19: $(libdl) |
127 |
+$(objpfx)tst-tls19.out: $(objpfx)tst-tls19mod1.so |
128 |
+ |
129 |
CFLAGS-tst-align.c = $(stack-align-test-flags) |
130 |
CFLAGS-tst-align2.c = $(stack-align-test-flags) |
131 |
CFLAGS-tst-alignmod.c = $(stack-align-test-flags) |
132 |
diff --git a/elf/dl-open.c b/elf/dl-open.c |
133 |
index cf8e8cc..8d90b56 100644 |
134 |
--- a/elf/dl-open.c |
135 |
+++ b/elf/dl-open.c |
136 |
@@ -347,6 +347,7 @@ dl_open_worker (void *a) |
137 |
/* If the file is not loaded now as a dependency, add the search |
138 |
list of the newly loaded object to the scope. */ |
139 |
bool any_tls = false; |
140 |
+ unsigned int first_static_tls = new->l_searchlist.r_nlist; |
141 |
for (unsigned int i = 0; i < new->l_searchlist.r_nlist; ++i) |
142 |
{ |
143 |
struct link_map *imap = new->l_searchlist.r_list[i]; |
144 |
@@ -425,30 +426,9 @@ dl_open_worker (void *a) |
145 |
might have to increase its size. */ |
146 |
_dl_add_to_slotinfo (imap); |
147 |
|
148 |
- if (imap->l_need_tls_init) |
149 |
- { |
150 |
- /* For static TLS we have to allocate the memory here |
151 |
- and now. This includes allocating memory in the DTV. |
152 |
- But we cannot change any DTV other than our own. So, |
153 |
- if we cannot guarantee that there is room in the DTV |
154 |
- we don't even try it and fail the load. |
155 |
- |
156 |
- XXX We could track the minimum DTV slots allocated in |
157 |
- all threads. */ |
158 |
- if (! RTLD_SINGLE_THREAD_P && imap->l_tls_modid > DTV_SURPLUS) |
159 |
- _dl_signal_error (0, "dlopen", NULL, N_("\ |
160 |
-cannot load any more object with static TLS")); |
161 |
- |
162 |
- imap->l_need_tls_init = 0; |
163 |
-#ifdef SHARED |
164 |
- /* Update the slot information data for at least the |
165 |
- generation of the DSO we are allocating data for. */ |
166 |
- _dl_update_slotinfo (imap->l_tls_modid); |
167 |
-#endif |
168 |
- |
169 |
- GL(dl_init_static_tls) (imap); |
170 |
- assert (imap->l_need_tls_init == 0); |
171 |
- } |
172 |
+ if (imap->l_need_tls_init |
173 |
+ && first_static_tls == new->l_searchlist.r_nlist) |
174 |
+ first_static_tls = i; |
175 |
|
176 |
/* We have to bump the generation counter. */ |
177 |
any_tls = true; |
178 |
@@ -460,6 +440,40 @@ cannot load any more object with static TLS")); |
179 |
_dl_fatal_printf (N_("\ |
180 |
TLS generation counter wrapped! Please report this.")); |
181 |
|
182 |
+ /* We need a second pass for static tls data, because _dl_update_slotinfo |
183 |
+ must not be run while calls to _dl_add_to_slotinfo are still pending. */ |
184 |
+ for (unsigned int i = first_static_tls; i < new->l_searchlist.r_nlist; ++i) |
185 |
+ { |
186 |
+ struct link_map *imap = new->l_searchlist.r_list[i]; |
187 |
+ |
188 |
+ if (imap->l_need_tls_init |
189 |
+ && ! imap->l_init_called |
190 |
+ && imap->l_tls_blocksize > 0) |
191 |
+ { |
192 |
+ /* For static TLS we have to allocate the memory here and |
193 |
+ now. This includes allocating memory in the DTV. But we |
194 |
+ cannot change any DTV other than our own. So, if we |
195 |
+ cannot guarantee that there is room in the DTV we don't |
196 |
+ even try it and fail the load. |
197 |
+ |
198 |
+ XXX We could track the minimum DTV slots allocated in |
199 |
+ all threads. */ |
200 |
+ if (! RTLD_SINGLE_THREAD_P && imap->l_tls_modid > DTV_SURPLUS) |
201 |
+ _dl_signal_error (0, "dlopen", NULL, N_("\ |
202 |
+cannot load any more object with static TLS")); |
203 |
+ |
204 |
+ imap->l_need_tls_init = 0; |
205 |
+#ifdef SHARED |
206 |
+ /* Update the slot information data for at least the |
207 |
+ generation of the DSO we are allocating data for. */ |
208 |
+ _dl_update_slotinfo (imap->l_tls_modid); |
209 |
+#endif |
210 |
+ |
211 |
+ GL(dl_init_static_tls) (imap); |
212 |
+ assert (imap->l_need_tls_init == 0); |
213 |
+ } |
214 |
+ } |
215 |
+ |
216 |
/* Run the initializer functions of new objects. */ |
217 |
_dl_init (new, args->argc, args->argv, args->env); |
218 |
|
219 |
diff --git a/elf/tst-tls19.c b/elf/tst-tls19.c |
220 |
new file mode 100644 |
221 |
index 0000000..acbc1d6 |
222 |
--- /dev/null |
223 |
+++ b/elf/tst-tls19.c |
224 |
@@ -0,0 +1,27 @@ |
225 |
+// BZ 12453 |
226 |
+#include <stdio.h> |
227 |
+#include <dlfcn.h> |
228 |
+ |
229 |
+ |
230 |
+static int |
231 |
+do_test (void) |
232 |
+{ |
233 |
+ void* dl = dlopen ("tst-tls19mod1.so", RTLD_LAZY | RTLD_GLOBAL); |
234 |
+ if (dl == NULL) |
235 |
+ { |
236 |
+ printf ("Error loading tst-tls19mod1.so: %s\n", dlerror ()); |
237 |
+ return 1; |
238 |
+ } |
239 |
+ |
240 |
+ int (*fn) (void) = dlsym (dl, "foo"); |
241 |
+ if (fn == NULL) |
242 |
+ { |
243 |
+ printf("Error obtaining symbol foo\n"); |
244 |
+ return 1; |
245 |
+ } |
246 |
+ |
247 |
+ return fn (); |
248 |
+} |
249 |
+ |
250 |
+#define TEST_FUNCTION do_test () |
251 |
+#include "../test-skeleton.c" |
252 |
diff --git a/elf/tst-tls19mod1.c b/elf/tst-tls19mod1.c |
253 |
new file mode 100644 |
254 |
index 0000000..2790097 |
255 |
--- /dev/null |
256 |
+++ b/elf/tst-tls19mod1.c |
257 |
@@ -0,0 +1,15 @@ |
258 |
+#include <stdio.h> |
259 |
+ |
260 |
+extern int bar (void); |
261 |
+extern int baz (void); |
262 |
+ |
263 |
+int |
264 |
+foo (void) |
265 |
+{ |
266 |
+ int v1 = bar (); |
267 |
+ int v2 = baz (); |
268 |
+ |
269 |
+ printf ("bar=%d, baz=%d\n", v1, v2); |
270 |
+ |
271 |
+ return v1 != 666 || v2 != 42; |
272 |
+} |
273 |
diff --git a/elf/tst-tls19mod2.c b/elf/tst-tls19mod2.c |
274 |
new file mode 100644 |
275 |
index 0000000..cae702f |
276 |
--- /dev/null |
277 |
+++ b/elf/tst-tls19mod2.c |
278 |
@@ -0,0 +1,13 @@ |
279 |
+static int __thread tbar __attribute__ ((tls_model ("initial-exec"))) = 666; |
280 |
+ |
281 |
+void |
282 |
+setter (int a) |
283 |
+{ |
284 |
+ tbar = a; |
285 |
+} |
286 |
+ |
287 |
+int |
288 |
+bar (void) |
289 |
+{ |
290 |
+ return tbar; |
291 |
+} |
292 |
diff --git a/elf/tst-tls19mod3.c b/elf/tst-tls19mod3.c |
293 |
new file mode 100644 |
294 |
index 0000000..e7b2801 |
295 |
--- /dev/null |
296 |
+++ b/elf/tst-tls19mod3.c |
297 |
@@ -0,0 +1,16 @@ |
298 |
+#include <stdio.h> |
299 |
+ |
300 |
+static int __thread tbaz __attribute__ ((tls_model ("local-dynamic"))) = 42; |
301 |
+ |
302 |
+void |
303 |
+setter2 (int a) |
304 |
+{ |
305 |
+ tbaz = a; |
306 |
+} |
307 |
+ |
308 |
+int |
309 |
+baz (void) |
310 |
+{ |
311 |
+ printf ("&tbaz=%p\n", &tbaz); |
312 |
+ return tbaz; |
313 |
+} |
314 |
-- |
315 |
1.7.5.rc3 |