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.6 src/patchsets/glibc/2.12.2/README.history |
10 |
|
11 |
file : http://sources.gentoo.org/viewvc.cgi/gentoo/src/patchsets/glibc/2.12.2/README.history?rev=1.6&view=markup |
12 |
plain: http://sources.gentoo.org/viewvc.cgi/gentoo/src/patchsets/glibc/2.12.2/README.history?rev=1.6&content-type=text/plain |
13 |
diff : http://sources.gentoo.org/viewvc.cgi/gentoo/src/patchsets/glibc/2.12.2/README.history?r1=1.5&r2=1.6 |
14 |
|
15 |
Index: README.history |
16 |
=================================================================== |
17 |
RCS file: /var/cvsroot/gentoo/src/patchsets/glibc/2.12.2/README.history,v |
18 |
retrieving revision 1.5 |
19 |
retrieving revision 1.6 |
20 |
diff -u -r1.5 -r1.6 |
21 |
--- README.history 28 May 2011 17:54:51 -0000 1.5 |
22 |
+++ README.history 28 May 2011 18:44:57 -0000 1.6 |
23 |
@@ -1,3 +1,6 @@ |
24 |
+4 [pending] |
25 |
+ + 0043_all_glibc-2.12-broken-tls-init.patch |
26 |
+ |
27 |
3 23.05.2011 |
28 |
U 1505_hppa_glibc-2.11-hppa-nptl.patch |
29 |
+ 6532_all_sparc64-tls-cross-test.patch |
30 |
|
31 |
|
32 |
|
33 |
1.1 src/patchsets/glibc/2.12.2/0043_all_glibc-2.12-broken-tls-init.patch |
34 |
|
35 |
file : http://sources.gentoo.org/viewvc.cgi/gentoo/src/patchsets/glibc/2.12.2/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.12.2/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 |
@@ -1,5 +1,5 @@ |
137 |
/* Load a shared object at runtime, relocate it, and run its initializer. |
138 |
- Copyright (C) 1996-2007, 2009, 2010 Free Software Foundation, Inc. |
139 |
+ Copyright (C) 1996-2007, 2009, 2010, 2011 Free Software Foundation, Inc. |
140 |
This file is part of the GNU C Library. |
141 |
|
142 |
The GNU C Library is free software; you can redistribute it and/or |
143 |
@@ -347,6 +347,7 @@ dl_open_worker (void *a) |
144 |
/* If the file is not loaded now as a dependency, add the search |
145 |
list of the newly loaded object to the scope. */ |
146 |
bool any_tls = false; |
147 |
+ unsigned int first_static_tls = new->l_searchlist.r_nlist; |
148 |
for (unsigned int i = 0; i < new->l_searchlist.r_nlist; ++i) |
149 |
{ |
150 |
struct link_map *imap = new->l_searchlist.r_list[i]; |
151 |
@@ -425,30 +426,9 @@ dl_open_worker (void *a) |
152 |
might have to increase its size. */ |
153 |
_dl_add_to_slotinfo (imap); |
154 |
|
155 |
- if (imap->l_need_tls_init) |
156 |
- { |
157 |
- /* For static TLS we have to allocate the memory here |
158 |
- and now. This includes allocating memory in the DTV. |
159 |
- But we cannot change any DTV other than our own. So, |
160 |
- if we cannot guarantee that there is room in the DTV |
161 |
- we don't even try it and fail the load. |
162 |
- |
163 |
- XXX We could track the minimum DTV slots allocated in |
164 |
- all threads. */ |
165 |
- if (! RTLD_SINGLE_THREAD_P && imap->l_tls_modid > DTV_SURPLUS) |
166 |
- _dl_signal_error (0, "dlopen", NULL, N_("\ |
167 |
-cannot load any more object with static TLS")); |
168 |
- |
169 |
- imap->l_need_tls_init = 0; |
170 |
-#ifdef SHARED |
171 |
- /* Update the slot information data for at least the |
172 |
- generation of the DSO we are allocating data for. */ |
173 |
- _dl_update_slotinfo (imap->l_tls_modid); |
174 |
-#endif |
175 |
- |
176 |
- GL(dl_init_static_tls) (imap); |
177 |
- assert (imap->l_need_tls_init == 0); |
178 |
- } |
179 |
+ if (imap->l_need_tls_init |
180 |
+ && first_static_tls == new->l_searchlist.r_nlist) |
181 |
+ first_static_tls = i; |
182 |
|
183 |
/* We have to bump the generation counter. */ |
184 |
any_tls = true; |
185 |
@@ -460,6 +440,40 @@ cannot load any more object with static TLS")); |
186 |
_dl_fatal_printf (N_("\ |
187 |
TLS generation counter wrapped! Please report this.")); |
188 |
|
189 |
+ /* We need a second pass for static tls data, because _dl_update_slotinfo |
190 |
+ must not be run while calls to _dl_add_to_slotinfo are still pending. */ |
191 |
+ for (unsigned int i = first_static_tls; i < new->l_searchlist.r_nlist; ++i) |
192 |
+ { |
193 |
+ struct link_map *imap = new->l_searchlist.r_list[i]; |
194 |
+ |
195 |
+ if (imap->l_need_tls_init |
196 |
+ && ! imap->l_init_called |
197 |
+ && imap->l_tls_blocksize > 0) |
198 |
+ { |
199 |
+ /* For static TLS we have to allocate the memory here and |
200 |
+ now. This includes allocating memory in the DTV. But we |
201 |
+ cannot change any DTV other than our own. So, if we |
202 |
+ cannot guarantee that there is room in the DTV we don't |
203 |
+ even try it and fail the load. |
204 |
+ |
205 |
+ XXX We could track the minimum DTV slots allocated in |
206 |
+ all threads. */ |
207 |
+ if (! RTLD_SINGLE_THREAD_P && imap->l_tls_modid > DTV_SURPLUS) |
208 |
+ _dl_signal_error (0, "dlopen", NULL, N_("\ |
209 |
+cannot load any more object with static TLS")); |
210 |
+ |
211 |
+ imap->l_need_tls_init = 0; |
212 |
+#ifdef SHARED |
213 |
+ /* Update the slot information data for at least the |
214 |
+ generation of the DSO we are allocating data for. */ |
215 |
+ _dl_update_slotinfo (imap->l_tls_modid); |
216 |
+#endif |
217 |
+ |
218 |
+ GL(dl_init_static_tls) (imap); |
219 |
+ assert (imap->l_need_tls_init == 0); |
220 |
+ } |
221 |
+ } |
222 |
+ |
223 |
/* Run the initializer functions of new objects. */ |
224 |
_dl_init (new, args->argc, args->argv, args->env); |
225 |
|
226 |
diff --git a/elf/tst-tls19.c b/elf/tst-tls19.c |
227 |
new file mode 100644 |
228 |
index 0000000..acbc1d6 |
229 |
--- /dev/null |
230 |
+++ b/elf/tst-tls19.c |
231 |
@@ -0,0 +1,27 @@ |
232 |
+// BZ 12453 |
233 |
+#include <stdio.h> |
234 |
+#include <dlfcn.h> |
235 |
+ |
236 |
+ |
237 |
+static int |
238 |
+do_test (void) |
239 |
+{ |
240 |
+ void* dl = dlopen ("tst-tls19mod1.so", RTLD_LAZY | RTLD_GLOBAL); |
241 |
+ if (dl == NULL) |
242 |
+ { |
243 |
+ printf ("Error loading tst-tls19mod1.so: %s\n", dlerror ()); |
244 |
+ return 1; |
245 |
+ } |
246 |
+ |
247 |
+ int (*fn) (void) = dlsym (dl, "foo"); |
248 |
+ if (fn == NULL) |
249 |
+ { |
250 |
+ printf("Error obtaining symbol foo\n"); |
251 |
+ return 1; |
252 |
+ } |
253 |
+ |
254 |
+ return fn (); |
255 |
+} |
256 |
+ |
257 |
+#define TEST_FUNCTION do_test () |
258 |
+#include "../test-skeleton.c" |
259 |
diff --git a/elf/tst-tls19mod1.c b/elf/tst-tls19mod1.c |
260 |
new file mode 100644 |
261 |
index 0000000..2790097 |
262 |
--- /dev/null |
263 |
+++ b/elf/tst-tls19mod1.c |
264 |
@@ -0,0 +1,15 @@ |
265 |
+#include <stdio.h> |
266 |
+ |
267 |
+extern int bar (void); |
268 |
+extern int baz (void); |
269 |
+ |
270 |
+int |
271 |
+foo (void) |
272 |
+{ |
273 |
+ int v1 = bar (); |
274 |
+ int v2 = baz (); |
275 |
+ |
276 |
+ printf ("bar=%d, baz=%d\n", v1, v2); |
277 |
+ |
278 |
+ return v1 != 666 || v2 != 42; |
279 |
+} |
280 |
diff --git a/elf/tst-tls19mod2.c b/elf/tst-tls19mod2.c |
281 |
new file mode 100644 |
282 |
index 0000000..cae702f |
283 |
--- /dev/null |
284 |
+++ b/elf/tst-tls19mod2.c |
285 |
@@ -0,0 +1,13 @@ |
286 |
+static int __thread tbar __attribute__ ((tls_model ("initial-exec"))) = 666; |
287 |
+ |
288 |
+void |
289 |
+setter (int a) |
290 |
+{ |
291 |
+ tbar = a; |
292 |
+} |
293 |
+ |
294 |
+int |
295 |
+bar (void) |
296 |
+{ |
297 |
+ return tbar; |
298 |
+} |
299 |
diff --git a/elf/tst-tls19mod3.c b/elf/tst-tls19mod3.c |
300 |
new file mode 100644 |
301 |
index 0000000..e7b2801 |
302 |
--- /dev/null |
303 |
+++ b/elf/tst-tls19mod3.c |
304 |
@@ -0,0 +1,16 @@ |
305 |
+#include <stdio.h> |
306 |
+ |
307 |
+static int __thread tbaz __attribute__ ((tls_model ("local-dynamic"))) = 42; |
308 |
+ |
309 |
+void |
310 |
+setter2 (int a) |
311 |
+{ |
312 |
+ tbaz = a; |
313 |
+} |
314 |
+ |
315 |
+int |
316 |
+baz (void) |
317 |
+{ |
318 |
+ printf ("&tbaz=%p\n", &tbaz); |
319 |
+ return tbaz; |
320 |
+} |
321 |
-- |
322 |
1.7.5.rc3 |