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 <[email protected]>  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  <[email protected]>
+
+       [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 <[email protected]>.
+
+--- 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);
+ 
+


-- 
To UNSUBSCRIBE, email to [email protected]
with a subject of "unsubscribe". Trouble? Contact [email protected]
Archive: http://lists.debian.org/[email protected]

Reply via email to