Gentoo Archives: gentoo-commits

From: "Mike Frysinger (vapier)" <vapier@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] gentoo commit in src/patchsets/glibc/2.12.2: README.history 0043_all_glibc-2.12-broken-tls-init.patch
Date: Sat, 28 May 2011 18:45:10
Message-Id: 20110528184457.7DBA520054@flycatcher.gentoo.org
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