r5077 - in glibc-package/branches/glibc-branch-squeeze/debian: . patches/any
Author: aurel32
Date: 2011-12-13 10:14:56 +0000 (Tue, 13 Dec 2011)
New Revision: 5077
Added:
glibc-package/branches/glibc-branch-squeeze/debian/patches/any/cvs-dlopen-tls.diff
Modified:
glibc-package/branches/glibc-branch-squeeze/debian/changelog
Log:
* patches/any/cvs-dlopen-tls.diff: fix handling of static TLS in
dlopen'ed objects. Closes: #637239.
Modified: glibc-package/branches/glibc-branch-squeeze/debian/changelog
===================================================================
--- glibc-package/branches/glibc-branch-squeeze/debian/changelog 2011-12-12 23:10:21 UTC (rev 5076)
+++ glibc-package/branches/glibc-branch-squeeze/debian/changelog 2011-12-13 10:14:56 UTC (rev 5077)
@@ -55,6 +55,8 @@
* patches/any/cvs-statvfs-mount-flags.diff: get the mount flags directly
from the kernel when possible instead of parsing /proc/mounts. Closes:
#639897.
+ * patches/any/cvs-dlopen-tls.diff: fix handling of static TLS in
+ dlopen'ed objects. Closes: #637239.
-- Aurelien Jarno <aurel32@debian.org> Sat, 11 Jun 2011 18:12:35 +0200
Added: glibc-package/branches/glibc-branch-squeeze/debian/patches/any/cvs-dlopen-tls.diff
===================================================================
--- glibc-package/branches/glibc-branch-squeeze/debian/patches/any/cvs-dlopen-tls.diff (rev 0)
+++ glibc-package/branches/glibc-branch-squeeze/debian/patches/any/cvs-dlopen-tls.diff 2011-12-13 10:14:56 UTC (rev 5077)
@@ -0,0 +1,93 @@
+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.
+ Patch mostly by Martin von Gagern <Martin.vGagern@gmx.net>.
+
+--- a/elf/dl-open.c
++++ b/elf/dl-open.c
+@@ -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);
+
+
Reply to: