r4864 - in glibc-package/trunk/debian: . patches patches/any
Author: aurel32
Date: 2011-08-10 11:27:26 +0000 (Wed, 10 Aug 2011)
New Revision: 4864
Added:
glibc-package/trunk/debian/patches/any/cvs-dlopen-tls.diff
Modified:
glibc-package/trunk/debian/changelog
glibc-package/trunk/debian/patches/series
Log:
* Add debian/patches/cvs-dlopen-tls.diff to fix handling of static TLS in
dlopen'ed objects. Closes: #637239.
Modified: glibc-package/trunk/debian/changelog
===================================================================
--- glibc-package/trunk/debian/changelog 2011-08-09 18:00:14 UTC (rev 4863)
+++ glibc-package/trunk/debian/changelog 2011-08-10 11:27:26 UTC (rev 4864)
@@ -1,6 +1,8 @@
eglibc (2.13-17) UNRELEASED; urgency=low
* Improve libc.NEWS to also include headers.
+ * Add debian/patches/cvs-dlopen-tls.diff to fix handling of static TLS in
+ dlopen'ed objects. Closes: #637239.
-- Aurelien Jarno <aurel32@debian.org> Tue, 09 Aug 2011 11:40:02 +0200
Added: glibc-package/trunk/debian/patches/any/cvs-dlopen-tls.diff
===================================================================
--- glibc-package/trunk/debian/patches/any/cvs-dlopen-tls.diff (rev 0)
+++ glibc-package/trunk/debian/patches/any/cvs-dlopen-tls.diff 2011-08-10 11:27:26 UTC (rev 4864)
@@ -0,0 +1,249 @@
+2011-05-14 Ulrich Drepper <drepper@gmail.com>
+
+ [BZ #12453]
+ * elf/dl-open.c (dl_open_worker): Delay calls to _dl_update_slotinfo
+ until all modules are registered in the DTV.
+ * elf/Makefile: Add rules to build and run tst-tls19.
+ * elf/tst-tls19.c: New file.
+ * elf/tst-tls19mod1.c: New file.
+ * elf/tst-tls19mod2.c: New file.
+ * elf/tst-tls19mod3.c: New file.
+ Patch mostly by Martin von Gagern <Martin.vGagern@gmx.net>.
+
+diff --git a/elf/Makefile b/elf/Makefile
+index 8d9657d..6efb86c 100644
+--- a/elf/Makefile
++++ b/elf/Makefile
+@@ -76,6 +76,7 @@ distribute := rtld-Rules \
+ tst-tlsmod12.c tst-tls10.h tst-alignmod.c tst-alignmod2.c \
+ circlemod1.c circlemod1a.c circlemod2.c circlemod2a.c \
+ circlemod3.c circlemod3a.c nodlopenmod2.c \
++ tst-tls19mod1.c tst-tls19mod2.c tst-tls19mod3.c \
+ tls-macros.h \
+ reldep8mod1.c reldep8mod2.c reldep8mod3.c \
+ nodel2mod1.c nodel2mod2.c nodel2mod3.c \
+@@ -194,7 +195,7 @@ tests += loadtest restest1 preloadtest loadfail multiload origtest resolvfail \
+ restest2 next dblload dblunload reldep5 reldep6 reldep7 reldep8 \
+ circleload1 tst-tls3 tst-tls4 tst-tls5 tst-tls6 tst-tls7 tst-tls8 \
+ tst-tls10 tst-tls11 tst-tls12 tst-tls13 tst-tls14 tst-tls15 \
+- tst-tls16 tst-tls17 tst-tls18 tst-tls-dlinfo \
++ tst-tls16 tst-tls17 tst-tls18 tst-tls19 tst-tls-dlinfo \
+ tst-align tst-align2 $(tests-execstack-$(have-z-execstack)) \
+ tst-dlmodcount tst-dlopenrpath tst-deep1 \
+ tst-dlmopen1 tst-dlmopen2 tst-dlmopen3 \
+@@ -240,6 +241,7 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \
+ tst-tlsmod13 tst-tlsmod13a tst-tlsmod14a tst-tlsmod14b \
+ tst-tlsmod15a tst-tlsmod15b tst-tlsmod16a tst-tlsmod16b \
+ $(tlsmod17a-modules) tst-tlsmod17b $(tlsmod18a-modules) \
++ tst-tls19mod1 tst-tls19mod2 tst-tls19mod3 \
+ circlemod1 circlemod1a circlemod2 circlemod2a \
+ circlemod3 circlemod3a \
+ reldep8mod1 reldep8mod2 reldep8mod3 \
+@@ -525,6 +527,8 @@ $(objpfx)tst-tlsmod13a.so: $(objpfx)tst-tlsmod13.so
+ # For tst-tls9-static, make sure the modules it dlopens have libc.so in DT_NEEDED
+ $(objpfx)tst-tlsmod5.so: $(common-objpfx)libc.so
+ $(objpfx)tst-tlsmod6.so: $(common-objpfx)libc.so
++$(objpfx)tst-tls19mod1.so: $(objpfx)tst-tls19mod2.so $(objpfx)tst-tls19mod3.so
++$(objpfx)tst-tls19mod3.so: $(objpfx)ld.so
+ $(objpfx)reldep8mod3.so: $(objpfx)reldep8mod1.so $(objpfx)reldep8mod2.so
+ $(objpfx)nodel2mod3.so: $(objpfx)nodel2mod1.so $(objpfx)nodel2mod2.so
+ $(objpfx)reldep9mod2.so: $(objpfx)reldep9mod1.so
+@@ -822,6 +826,9 @@ $(patsubst %,$(objpfx)%.os,$(tlsmod18a-modules)): $(objpfx)tst-tlsmod18a%.os : t
+ $(compile-command.c) -DN=$*
+ $(patsubst %,$(objpfx)%.so,$(tlsmod18a-modules)): $(objpfx)tst-tlsmod18a%.so: $(objpfx)ld.so
+
++$(objpfx)tst-tls19: $(libdl)
++$(objpfx)tst-tls19.out: $(objpfx)tst-tls19mod1.so
++
+ CFLAGS-tst-align.c = $(stack-align-test-flags)
+ CFLAGS-tst-align2.c = $(stack-align-test-flags)
+ CFLAGS-tst-alignmod.c = $(stack-align-test-flags)
+diff --git a/elf/dl-open.c b/elf/dl-open.c
+index cf8e8cc..8d90b56 100644
+--- a/elf/dl-open.c
++++ b/elf/dl-open.c
+@@ -1,5 +1,5 @@
+ /* Load a shared object at runtime, relocate it, and run its initializer.
+- Copyright (C) 1996-2007, 2009, 2010 Free Software Foundation, Inc.
++ Copyright (C) 1996-2007, 2009, 2010, 2011 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+@@ -347,6 +347,7 @@ dl_open_worker (void *a)
+ /* If the file is not loaded now as a dependency, add the search
+ list of the newly loaded object to the scope. */
+ bool any_tls = false;
++ unsigned int first_static_tls = new->l_searchlist.r_nlist;
+ for (unsigned int i = 0; i < new->l_searchlist.r_nlist; ++i)
+ {
+ struct link_map *imap = new->l_searchlist.r_list[i];
+@@ -425,30 +426,9 @@ dl_open_worker (void *a)
+ might have to increase its size. */
+ _dl_add_to_slotinfo (imap);
+
+- if (imap->l_need_tls_init)
+- {
+- /* For static TLS we have to allocate the memory here
+- and now. This includes allocating memory in the DTV.
+- But we cannot change any DTV other than our own. So,
+- if we cannot guarantee that there is room in the DTV
+- we don't even try it and fail the load.
+-
+- XXX We could track the minimum DTV slots allocated in
+- all threads. */
+- if (! RTLD_SINGLE_THREAD_P && imap->l_tls_modid > DTV_SURPLUS)
+- _dl_signal_error (0, "dlopen", NULL, N_("\
+-cannot load any more object with static TLS"));
+-
+- imap->l_need_tls_init = 0;
+-#ifdef SHARED
+- /* Update the slot information data for at least the
+- generation of the DSO we are allocating data for. */
+- _dl_update_slotinfo (imap->l_tls_modid);
+-#endif
+-
+- GL(dl_init_static_tls) (imap);
+- assert (imap->l_need_tls_init == 0);
+- }
++ if (imap->l_need_tls_init
++ && first_static_tls == new->l_searchlist.r_nlist)
++ first_static_tls = i;
+
+ /* We have to bump the generation counter. */
+ any_tls = true;
+@@ -460,6 +440,40 @@ cannot load any more object with static TLS"));
+ _dl_fatal_printf (N_("\
+ TLS generation counter wrapped! Please report this."));
+
++ /* We need a second pass for static tls data, because _dl_update_slotinfo
++ must not be run while calls to _dl_add_to_slotinfo are still pending. */
++ for (unsigned int i = first_static_tls; i < new->l_searchlist.r_nlist; ++i)
++ {
++ struct link_map *imap = new->l_searchlist.r_list[i];
++
++ if (imap->l_need_tls_init
++ && ! imap->l_init_called
++ && imap->l_tls_blocksize > 0)
++ {
++ /* For static TLS we have to allocate the memory here and
++ now. This includes allocating memory in the DTV. But we
++ cannot change any DTV other than our own. So, if we
++ cannot guarantee that there is room in the DTV we don't
++ even try it and fail the load.
++
++ XXX We could track the minimum DTV slots allocated in
++ all threads. */
++ if (! RTLD_SINGLE_THREAD_P && imap->l_tls_modid > DTV_SURPLUS)
++ _dl_signal_error (0, "dlopen", NULL, N_("\
++cannot load any more object with static TLS"));
++
++ imap->l_need_tls_init = 0;
++#ifdef SHARED
++ /* Update the slot information data for at least the
++ generation of the DSO we are allocating data for. */
++ _dl_update_slotinfo (imap->l_tls_modid);
++#endif
++
++ GL(dl_init_static_tls) (imap);
++ assert (imap->l_need_tls_init == 0);
++ }
++ }
++
+ /* Run the initializer functions of new objects. */
+ _dl_init (new, args->argc, args->argv, args->env);
+
+diff --git a/elf/tst-tls19.c b/elf/tst-tls19.c
+new file mode 100644
+index 0000000..acbc1d6
+--- /dev/null
++++ b/elf/tst-tls19.c
+@@ -0,0 +1,27 @@
++// BZ 12453
++#include <stdio.h>
++#include <dlfcn.h>
++
++
++static int
++do_test (void)
++{
++ void* dl = dlopen ("tst-tls19mod1.so", RTLD_LAZY | RTLD_GLOBAL);
++ if (dl == NULL)
++ {
++ printf ("Error loading tst-tls19mod1.so: %s\n", dlerror ());
++ return 1;
++ }
++
++ int (*fn) (void) = dlsym (dl, "foo");
++ if (fn == NULL)
++ {
++ printf("Error obtaining symbol foo\n");
++ return 1;
++ }
++
++ return fn ();
++}
++
++#define TEST_FUNCTION do_test ()
++#include "../test-skeleton.c"
+diff --git a/elf/tst-tls19mod1.c b/elf/tst-tls19mod1.c
+new file mode 100644
+index 0000000..2790097
+--- /dev/null
++++ b/elf/tst-tls19mod1.c
+@@ -0,0 +1,15 @@
++#include <stdio.h>
++
++extern int bar (void);
++extern int baz (void);
++
++int
++foo (void)
++{
++ int v1 = bar ();
++ int v2 = baz ();
++
++ printf ("bar=%d, baz=%d\n", v1, v2);
++
++ return v1 != 666 || v2 != 42;
++}
+diff --git a/elf/tst-tls19mod2.c b/elf/tst-tls19mod2.c
+new file mode 100644
+index 0000000..cae702f
+--- /dev/null
++++ b/elf/tst-tls19mod2.c
+@@ -0,0 +1,13 @@
++static int __thread tbar __attribute__ ((tls_model ("initial-exec"))) = 666;
++
++void
++setter (int a)
++{
++ tbar = a;
++}
++
++int
++bar (void)
++{
++ return tbar;
++}
+diff --git a/elf/tst-tls19mod3.c b/elf/tst-tls19mod3.c
+new file mode 100644
+index 0000000..e7b2801
+--- /dev/null
++++ b/elf/tst-tls19mod3.c
+@@ -0,0 +1,16 @@
++#include <stdio.h>
++
++static int __thread tbaz __attribute__ ((tls_model ("local-dynamic"))) = 42;
++
++void
++setter2 (int a)
++{
++ tbaz = a;
++}
++
++int
++baz (void)
++{
++ printf ("&tbaz=%p\n", &tbaz);
++ return tbaz;
++}
Modified: glibc-package/trunk/debian/patches/series
===================================================================
--- glibc-package/trunk/debian/patches/series 2011-08-09 18:00:14 UTC (rev 4863)
+++ glibc-package/trunk/debian/patches/series 2011-08-10 11:27:26 UTC (rev 4864)
@@ -275,3 +275,4 @@
any/cvs-ifunc.diff
any/submitted-resolv-init.diff
powerpc/submitted-ifunc.diff
+any/cvs-dlopen-tls.diff
Reply to: