]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
Fix TLS problems not handled by cherrypick
authorStan Shebs <stanshebs@google.com>
Tue, 10 Jul 2018 19:05:15 +0000 (12:05 -0700)
committerFangrui Song <i@maskray.me>
Sat, 28 Aug 2021 00:23:12 +0000 (17:23 -0700)
elf/dl-tls.c
nptl/allocatestack.c
sysdeps/generic/ldsodefs.h
sysdeps/unix/sysv/linux/dl-sysdep.c
sysdeps/unix/sysv/linux/dl-sysdep.h

index 7770ec3be51d609ef3f35bc45651ee5604c44294..5659adbba5a900a9a8efc10b7c19ac3bf7106f08 100644 (file)
@@ -535,11 +535,10 @@ _dl_allocate_tls (void *mem)
 rtld_hidden_def (_dl_allocate_tls)
 
 void
-internal_function
 _dl_clear_dtv (dtv_t *dtv)
 {
   for (size_t cnt = 0; cnt < dtv[-1].counter; ++cnt)
-    if (! dtv[1 + cnt].pointer.is_static
+    if (/*! dtv[1 + cnt].pointer.is_static */ 1
        && dtv[1 + cnt].pointer.val != TLS_DTV_UNALLOCATED)
       __signal_safe_free (dtv[1 + cnt].pointer.val);
   memset (dtv, '\0', (dtv[-1].counter + 1) * sizeof (dtv_t));
@@ -746,7 +745,6 @@ tls_get_addr_tail (GET_ADDR_ARGS, dtv_t *dtv, struct link_map *the_map)
 
       the_map = listp->slotinfo[idx].map;
     }
-#if 0
   sigset_t old;
   _dl_mask_all_signals (&old);
 
@@ -754,7 +752,6 @@ tls_get_addr_tail (GET_ADDR_ARGS, dtv_t *dtv, struct link_map *the_map)
      reentrancy.  */
   if (dtv[GET_ADDR_MODULE].pointer.val != TLS_DTV_UNALLOCATED)
     {
-      assert (dtv[GET_ADDR_MODULE].pointer.val != TLS_DTV_UNALLOCATED);
       _dl_unmask_signals (&old);
 
       return (char *) dtv[GET_ADDR_MODULE].pointer.val + GET_ADDR_OFFSET;
@@ -778,48 +775,7 @@ tls_get_addr_tail (GET_ADDR_ARGS, dtv_t *dtv, struct link_map *the_map)
       offset = the_map->l_tls_offset;
       assert (offset != NO_TLS_OFFSET);
     }
-  #endif
-
-  /* Make sure that, if a dlopen running in parallel forces the
-     variable into static storage, we'll wait until the address in the
-     static TLS block is set up, and use that.  If we're undecided
-     yet, make sure we make the decision holding the lock as well.  */
-  if (__glibc_unlikely (the_map->l_tls_offset
-                       != FORCED_DYNAMIC_TLS_OFFSET))
-    {
-      __rtld_lock_lock_recursive (GL(dl_load_lock));
-      if (__glibc_likely (the_map->l_tls_offset == NO_TLS_OFFSET))
-       {
-         the_map->l_tls_offset = FORCED_DYNAMIC_TLS_OFFSET;
-         __rtld_lock_unlock_recursive (GL(dl_load_lock));
-       }
-      else if (__glibc_likely (the_map->l_tls_offset
-                              != FORCED_DYNAMIC_TLS_OFFSET))
-       {
-#if TLS_TCB_AT_TP
-         void *p = (char *) THREAD_SELF - the_map->l_tls_offset;
-#elif TLS_DTV_AT_TP
-         void *p = (char *) THREAD_SELF + the_map->l_tls_offset + TLS_PRE_TCB_SIZE;
-#else
-# error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
-#endif
-         __rtld_lock_unlock_recursive (GL(dl_load_lock));
-
-         dtv[GET_ADDR_MODULE].pointer.to_free = NULL;
-         dtv[GET_ADDR_MODULE].pointer.val = p;
 
-         return (char *) p + GET_ADDR_OFFSET;
-       }
-      else
-       __rtld_lock_unlock_recursive (GL(dl_load_lock));
-    }
-  struct dtv_pointer result = allocate_and_init (the_map);
-  dtv[GET_ADDR_MODULE].pointer = result;
-  assert (result.to_free != NULL);
-
-  return (char *) result.val + GET_ADDR_OFFSET;
-
-#if 0
   if (offset == FORCED_DYNAMIC_TLS_OFFSET)
     {
       allocate_and_init (&dtv[GET_ADDR_MODULE], the_map);
@@ -835,7 +791,7 @@ tls_get_addr_tail (GET_ADDR_ARGS, dtv_t *dtv, struct link_map *the_map)
            threads to initialize it.  They'll eventually write
            to pointer.val, at which point we know they've fully
            completed initialization.  */
-         atomic_delay ();
+         atomic_spin_nop ();
        }
       /* Make sure we've picked up their initialization of the actual
         block; this pairs against the write barrier in
@@ -847,7 +803,6 @@ tls_get_addr_tail (GET_ADDR_ARGS, dtv_t *dtv, struct link_map *the_map)
   _dl_unmask_signals (&old);
 
   return (char *) dtv[GET_ADDR_MODULE].pointer.val + GET_ADDR_OFFSET;
-#endif
 }
 
 
index 37576562f8ef15e5655c0ab270747b79c482f33f..49bfc66b954d6fe351507af741c171d2d4b7ac8f 100644 (file)
@@ -1243,6 +1243,7 @@ init_one_static_tls (struct pthread *curp, struct link_map *map)
   memset (__mempcpy (dest, map->l_tls_initimage, map->l_tls_initimage_size),
          '\0', map->l_tls_blocksize - map->l_tls_initimage_size);
 
+#if 0 /* still needed? dtv refs gone in current code */
   /* Fill in the DTV slot so that a later LD/GD access will find it.  */
   dtv[map->l_tls_modid].pointer.is_static = true;
   /* Pairs against the read barrier in tls_get_attr_tail, guaranteeing
@@ -1250,7 +1251,7 @@ init_one_static_tls (struct pthread *curp, struct link_map *map)
      initimage write.  */
   atomic_write_barrier ();
   dtv[map->l_tls_modid].pointer.val = dest;
-
+#endif
 }
 
 void
index 7326e118449a31d523be4b5f9903e9311cacb309..a5822302b432bb74a7db32fbb715380c4067053d 100644 (file)
@@ -258,9 +258,9 @@ extern unsigned long int _dl_higher_prime_number (unsigned long int n)
 uint64_t _dl_strtoul (const char *, char **) attribute_hidden;
 
 /* Mask every signal, returning the previous sigmask in OLD.  */
-extern void _dl_mask_all_signals (sigset_t *old) internal_function;
+extern void _dl_mask_all_signals (sigset_t *old);
 /* Undo _dl_mask_all_signals.  */
-extern void _dl_unmask_signals (sigset_t *old) internal_function;
+extern void _dl_unmask_signals (sigset_t *old);
 
 /* Function used as argument for `_dl_receive_error' function.  The
    arguments are the error code, error string, and the objname the
@@ -1103,7 +1103,7 @@ rtld_hidden_proto (_dl_allocate_tls_init)
 
 /* Remove all allocated dynamic TLS regions from a DTV
    for reuse by new thread.  */
-extern void _dl_clear_dtv (dtv_t *dtv) internal_function;
+extern void _dl_clear_dtv (dtv_t *dtv);
 rtld_hidden_proto (_dl_clear_dtv)
 
 extern void *__signal_safe_memalign (size_t boundary, size_t size);
index f8d1d5d05835e5362944a65291ba6b3494fa7bf0..18fe7f330aead45ef1cfe36227eff59a94f02887 100644 (file)
@@ -134,7 +134,6 @@ _dl_discover_osversion (void)
 
 /* Mask every signal, returning the previous sigmask in OLD.  */
 void
-internal_function
 _dl_mask_all_signals (sigset_t *old)
 {
   int ret;
@@ -165,7 +164,6 @@ _dl_mask_all_signals (sigset_t *old)
 
 /* Return sigmask to what it was before a call to _dl_mask_all_signals.  */
 void
-internal_function
 _dl_unmask_signals (sigset_t *old)
 {
   int ret;
index 0c64545ed36993e6a1785ca9d7efee01ff6966d4..4c093218b971fb0056224ad0f6eca11cfa992cc2 100644 (file)
@@ -32,6 +32,6 @@ extern int _dl_discover_osversion (void) attribute_hidden;
 # define HAVE_DL_DISCOVER_OSVERSION    1
 
 #include <signal.h>
-void _dl_mask_all_signals (sigset_t *) internal_function;
-void _dl_unmask_all_signals (sigset_t *) internal_function;
+void _dl_mask_all_signals (sigset_t *);
+void _dl_unmask_all_signals (sigset_t *);
 #endif