public inbox for glibc-cvs@sourceware.org
help / color / mirror / Atom feed
* [glibc/maskray/grte] Add a case to async-signal-safe TLS to set static TLS instead of waiting for a dlopen that may not a
@ 2021-08-27 23:45 Fangrui Song
  0 siblings, 0 replies; 3+ messages in thread
From: Fangrui Song @ 2021-08-27 23:45 UTC (permalink / raw)
  To: glibc-cvs

https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=789c32e7b63e38d357fad40f4d3b286a608fa07b

commit 789c32e7b63e38d357fad40f4d3b286a608fa07b
Author: Stan Shebs <stanshebs@google.com>
Date:   Fri Nov 8 13:41:17 2019 -0800

    Add a case to async-signal-safe TLS to set static TLS instead of waiting for a dlopen that may not actually be happening.

Diff:
---
 elf/dl-tls.c | 27 +++++++++++++++++++++++++--
 1 file changed, 25 insertions(+), 2 deletions(-)

diff --git a/elf/dl-tls.c b/elf/dl-tls.c
index 592512f069..0ebd1fa040 100644
--- a/elf/dl-tls.c
+++ b/elf/dl-tls.c
@@ -931,8 +931,8 @@ tls_get_addr_tail (GET_ADDR_ARGS, dtv_t *dtv, struct link_map *the_map)
      into static storage.  If that happens, we have to be more careful
      about initializing the area, as that dlopen() will be iterating
      the threads to do so itself.  */
-  ptrdiff_t offset;
-  if ((offset = the_map->l_tls_offset) == NO_TLS_OFFSET)
+  ptrdiff_t offset = the_map->l_tls_offset;
+  if (offset == NO_TLS_OFFSET)
     {
       /* l_tls_offset starts out at NO_TLS_OFFSET, and all attempts to
 	 change it go from NO_TLS_OFFSET to some other value.  We use
@@ -957,6 +957,29 @@ tls_get_addr_tail (GET_ADDR_ARGS, dtv_t *dtv, struct link_map *the_map)
                           (int) sizeof (void *) * 2,
                           (unsigned long int) dtv[GET_ADDR_MODULE].pointer.val);
     }
+  /* It can happen that slot info updates will un-allocate a pointer (possibly
+     due to a bug elsewhere), which leaves us waiting indefinitely for the
+     dlopen that will never happen.  Emulate the async-signal-unsafe case above
+     and use a static TLS address.  */
+  else if (dtv[GET_ADDR_MODULE].pointer.val == TLS_DTV_UNALLOCATED)
+    {
+#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
+      dtv[GET_ADDR_MODULE].pointer.to_free = NULL;
+      dtv[GET_ADDR_MODULE].pointer.val = p;
+      if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_TLS))
+        _dl_debug_printf ("tls_get_addr_tail sets unallocated own dtv 0x%0*Zx module %lu pointer.val = 0x%0*Zx\n",
+                          (int) sizeof (void *) * 2,
+                          (unsigned long int) dtv,
+                          GET_ADDR_MODULE,
+                          (int) sizeof (void *) * 2,
+                          (unsigned long int) dtv[GET_ADDR_MODULE].pointer.val);
+    }
   else
     {
       void ** volatile pp = &dtv[GET_ADDR_MODULE].pointer.val;


^ permalink raw reply	[flat|nested] 3+ messages in thread

* [glibc/maskray/grte] Add a case to async-signal-safe TLS to set static TLS instead of waiting for a dlopen that may not a
@ 2021-08-28  0:32 Fangrui Song
  0 siblings, 0 replies; 3+ messages in thread
From: Fangrui Song @ 2021-08-28  0:32 UTC (permalink / raw)
  To: glibc-cvs

https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=d0d7b3d2b39501cbad941304b8ccc2675d6b88a9

commit d0d7b3d2b39501cbad941304b8ccc2675d6b88a9
Author: Stan Shebs <stanshebs@google.com>
Date:   Fri Nov 8 13:41:17 2019 -0800

    Add a case to async-signal-safe TLS to set static TLS instead of waiting for a dlopen that may not actually be happening.

Diff:
---
 elf/dl-tls.c | 27 +++++++++++++++++++++++++--
 1 file changed, 25 insertions(+), 2 deletions(-)

diff --git a/elf/dl-tls.c b/elf/dl-tls.c
index 592512f069..0ebd1fa040 100644
--- a/elf/dl-tls.c
+++ b/elf/dl-tls.c
@@ -931,8 +931,8 @@ tls_get_addr_tail (GET_ADDR_ARGS, dtv_t *dtv, struct link_map *the_map)
      into static storage.  If that happens, we have to be more careful
      about initializing the area, as that dlopen() will be iterating
      the threads to do so itself.  */
-  ptrdiff_t offset;
-  if ((offset = the_map->l_tls_offset) == NO_TLS_OFFSET)
+  ptrdiff_t offset = the_map->l_tls_offset;
+  if (offset == NO_TLS_OFFSET)
     {
       /* l_tls_offset starts out at NO_TLS_OFFSET, and all attempts to
 	 change it go from NO_TLS_OFFSET to some other value.  We use
@@ -957,6 +957,29 @@ tls_get_addr_tail (GET_ADDR_ARGS, dtv_t *dtv, struct link_map *the_map)
                           (int) sizeof (void *) * 2,
                           (unsigned long int) dtv[GET_ADDR_MODULE].pointer.val);
     }
+  /* It can happen that slot info updates will un-allocate a pointer (possibly
+     due to a bug elsewhere), which leaves us waiting indefinitely for the
+     dlopen that will never happen.  Emulate the async-signal-unsafe case above
+     and use a static TLS address.  */
+  else if (dtv[GET_ADDR_MODULE].pointer.val == TLS_DTV_UNALLOCATED)
+    {
+#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
+      dtv[GET_ADDR_MODULE].pointer.to_free = NULL;
+      dtv[GET_ADDR_MODULE].pointer.val = p;
+      if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_TLS))
+        _dl_debug_printf ("tls_get_addr_tail sets unallocated own dtv 0x%0*Zx module %lu pointer.val = 0x%0*Zx\n",
+                          (int) sizeof (void *) * 2,
+                          (unsigned long int) dtv,
+                          GET_ADDR_MODULE,
+                          (int) sizeof (void *) * 2,
+                          (unsigned long int) dtv[GET_ADDR_MODULE].pointer.val);
+    }
   else
     {
       void ** volatile pp = &dtv[GET_ADDR_MODULE].pointer.val;


^ permalink raw reply	[flat|nested] 3+ messages in thread

* [glibc/maskray/grte] Add a case to async-signal-safe TLS to set static TLS instead of waiting for a dlopen that may not a
@ 2021-08-28  0:28 Fangrui Song
  0 siblings, 0 replies; 3+ messages in thread
From: Fangrui Song @ 2021-08-28  0:28 UTC (permalink / raw)
  To: glibc-cvs

https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=d6b6245d8ee8babb55a73d8fbd89a51d7e81ba79

commit d6b6245d8ee8babb55a73d8fbd89a51d7e81ba79
Author: Stan Shebs <stanshebs@google.com>
Date:   Fri Nov 8 13:41:17 2019 -0800

    Add a case to async-signal-safe TLS to set static TLS instead of waiting for a dlopen that may not actually be happening.

Diff:
---
 elf/dl-tls.c | 27 +++++++++++++++++++++++++--
 1 file changed, 25 insertions(+), 2 deletions(-)

diff --git a/elf/dl-tls.c b/elf/dl-tls.c
index 592512f069..0ebd1fa040 100644
--- a/elf/dl-tls.c
+++ b/elf/dl-tls.c
@@ -931,8 +931,8 @@ tls_get_addr_tail (GET_ADDR_ARGS, dtv_t *dtv, struct link_map *the_map)
      into static storage.  If that happens, we have to be more careful
      about initializing the area, as that dlopen() will be iterating
      the threads to do so itself.  */
-  ptrdiff_t offset;
-  if ((offset = the_map->l_tls_offset) == NO_TLS_OFFSET)
+  ptrdiff_t offset = the_map->l_tls_offset;
+  if (offset == NO_TLS_OFFSET)
     {
       /* l_tls_offset starts out at NO_TLS_OFFSET, and all attempts to
 	 change it go from NO_TLS_OFFSET to some other value.  We use
@@ -957,6 +957,29 @@ tls_get_addr_tail (GET_ADDR_ARGS, dtv_t *dtv, struct link_map *the_map)
                           (int) sizeof (void *) * 2,
                           (unsigned long int) dtv[GET_ADDR_MODULE].pointer.val);
     }
+  /* It can happen that slot info updates will un-allocate a pointer (possibly
+     due to a bug elsewhere), which leaves us waiting indefinitely for the
+     dlopen that will never happen.  Emulate the async-signal-unsafe case above
+     and use a static TLS address.  */
+  else if (dtv[GET_ADDR_MODULE].pointer.val == TLS_DTV_UNALLOCATED)
+    {
+#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
+      dtv[GET_ADDR_MODULE].pointer.to_free = NULL;
+      dtv[GET_ADDR_MODULE].pointer.val = p;
+      if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_TLS))
+        _dl_debug_printf ("tls_get_addr_tail sets unallocated own dtv 0x%0*Zx module %lu pointer.val = 0x%0*Zx\n",
+                          (int) sizeof (void *) * 2,
+                          (unsigned long int) dtv,
+                          GET_ADDR_MODULE,
+                          (int) sizeof (void *) * 2,
+                          (unsigned long int) dtv[GET_ADDR_MODULE].pointer.val);
+    }
   else
     {
       void ** volatile pp = &dtv[GET_ADDR_MODULE].pointer.val;


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2021-08-28  0:32 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-08-27 23:45 [glibc/maskray/grte] Add a case to async-signal-safe TLS to set static TLS instead of waiting for a dlopen that may not a Fangrui Song
2021-08-28  0:28 Fangrui Song
2021-08-28  0:32 Fangrui Song

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).