[RFC,htl,v2,4/4] XXX: Attempt to get rid of most THREAD_GSCOPE_IN_TCB usages

Message ID 20210830152636.1334678-5-bugaevc@gmail.com
State Superseded
Headers
Series Rewrite THREAD_GSCOPE |

Checks

Context Check Description
dj/TryBot-apply_patch success Patch applied to master at the time it was sent
dj/TryBot-32bit success Build for i686

Commit Message

Sergey Bugaev Aug. 30, 2021, 3:26 p.m. UTC
  Try to do this by adding HTL- and NPTL-specific versions of
dl-support.c, dl-tls.c, and dl-tls_init_tp.c, and moving HTL and NPTL
specifics there.

The remaining user of THREAD_GSCOPE_IN_TCB is <ldsodefs.h>, which I'm
not sure how to handle. I see that there are sysdeps versions of it,
so it could be possible to create one for NPTL and one for HTL.

However, I don't see an existing way for these port-sepcific ldsodefs
versions to add their own members to struct rtld_global. One way to do
this would be to introduce a macro like LDSO_GLOBAL_EXTRA_MEMBERS, but
I'm not sure whether that's a good or even acceptable approach.

Signed-off-by: Sergey Bugaev <bugaevc@gmail.com>
---
 elf/dl-reloc.c                             | 21 ---------
 elf/dl-support.c                           | 14 ------
 elf/dl-tls.c                               | 39 ----------------
 sysdeps/htl/dl-support.c                   |  5 ++
 sysdeps/htl/dl-tls.c                       | 39 ++++++++++++++++
 {elf => sysdeps/htl}/dl-tls_init_tp.c      |  4 +-
 sysdeps/nptl/dl-support.c                  | 26 +++++++++++
 sysdeps/nptl/dl-tls.c                      | 53 ++++++++++++++++++++++
 sysdeps/unix/sysv/linux/alpha/dl-support.c |  2 +-
 9 files changed, 125 insertions(+), 78 deletions(-)
 create mode 100644 sysdeps/htl/dl-tls.c
 rename {elf => sysdeps/htl}/dl-tls_init_tp.c (93%)
 create mode 100644 sysdeps/nptl/dl-support.c
 create mode 100644 sysdeps/nptl/dl-tls.c
  

Patch

diff --git a/elf/dl-reloc.c b/elf/dl-reloc.c
index e13a672ade..0d97af752a 100644
--- a/elf/dl-reloc.c
+++ b/elf/dl-reloc.c
@@ -141,27 +141,6 @@  cannot allocate memory in static TLS block"));
     }
 }
 
-#if !THREAD_GSCOPE_IN_TCB
-/* Initialize static TLS area and DTV for current (only) thread.
-   libpthread implementations should provide their own hook
-   to handle all threads.  */
-void
-_dl_nothread_init_static_tls (struct link_map *map)
-{
-#if TLS_TCB_AT_TP
-  void *dest = (char *) THREAD_SELF - map->l_tls_offset;
-#elif TLS_DTV_AT_TP
-  void *dest = (char *) THREAD_SELF + map->l_tls_offset + TLS_PRE_TCB_SIZE;
-#else
-# error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
-#endif
-
-  /* Initialize the memory.  */
-  memset (__mempcpy (dest, map->l_tls_initimage, map->l_tls_initimage_size),
-	  '\0', map->l_tls_blocksize - map->l_tls_initimage_size);
-}
-#endif /* !THREAD_GSCOPE_IN_TCB */
-
 void
 _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
 		     int reloc_mode, int consider_profiling)
diff --git a/elf/dl-support.c b/elf/dl-support.c
index 68abf606ca..28d61bda51 100644
--- a/elf/dl-support.c
+++ b/elf/dl-support.c
@@ -183,20 +183,6 @@  uint64_t _dl_hwcap_mask;
  * executable but this isn't true for all platforms.  */
 ElfW(Word) _dl_stack_flags = DEFAULT_STACK_PERMS;
 
-#if THREAD_GSCOPE_IN_TCB
-list_t _dl_stack_used;
-list_t _dl_stack_user;
-list_t _dl_stack_cache;
-size_t _dl_stack_cache_actsize;
-uintptr_t _dl_in_flight_stack;
-int _dl_stack_cache_lock;
-#else
-/* If loading a shared object requires that we make the stack executable
-   when it was not, we do it by calling this function.
-   It returns an errno code or zero on success.  */
-int (*_dl_make_stack_executable_hook) (void **) = _dl_make_stack_executable;
-void (*_dl_init_static_tls) (struct link_map *) = &_dl_nothread_init_static_tls;
-#endif
 struct dl_scope_free_list *_dl_scope_free_list;
 
 #ifdef NEED_DL_SYSINFO
diff --git a/elf/dl-tls.c b/elf/dl-tls.c
index 423e380f7c..64797d2ed6 100644
--- a/elf/dl-tls.c
+++ b/elf/dl-tls.c
@@ -29,10 +29,6 @@ 
 #include <dl-tls.h>
 #include <ldsodefs.h>
 
-#if THREAD_GSCOPE_IN_TCB
-# include <list.h>
-#endif
-
 #define TUNABLE_NAMESPACE rtld
 #include <dl-tunables.h>
 
@@ -1057,38 +1053,3 @@  cannot create TLS data structures"));
 			    GL(dl_tls_generation) + 1);
     }
 }
-
-#if THREAD_GSCOPE_IN_TCB
-static inline void __attribute__((always_inline))
-init_one_static_tls (struct pthread *curp, struct link_map *map)
-{
-# if TLS_TCB_AT_TP
-  void *dest = (char *) curp - map->l_tls_offset;
-# elif TLS_DTV_AT_TP
-  void *dest = (char *) curp + map->l_tls_offset + TLS_PRE_TCB_SIZE;
-# else
-#  error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
-# endif
-
-  /* Initialize the memory.  */
-  memset (__mempcpy (dest, map->l_tls_initimage, map->l_tls_initimage_size),
-	  '\0', map->l_tls_blocksize - map->l_tls_initimage_size);
-}
-
-void
-_dl_init_static_tls (struct link_map *map)
-{
-  lll_lock (GL (dl_stack_cache_lock), LLL_PRIVATE);
-
-  /* Iterate over the list with system-allocated threads first.  */
-  list_t *runp;
-  list_for_each (runp, &GL (dl_stack_used))
-    init_one_static_tls (list_entry (runp, struct pthread, list), map);
-
-  /* Now the list with threads using user-allocated stacks.  */
-  list_for_each (runp, &GL (dl_stack_user))
-    init_one_static_tls (list_entry (runp, struct pthread, list), map);
-
-  lll_unlock (GL (dl_stack_cache_lock), LLL_PRIVATE);
-}
-#endif /* THREAD_GSCOPE_IN_TCB */
diff --git a/sysdeps/htl/dl-support.c b/sysdeps/htl/dl-support.c
index 21a391a59f..02c53af4c3 100644
--- a/sysdeps/htl/dl-support.c
+++ b/sysdeps/htl/dl-support.c
@@ -21,3 +21,8 @@ 
 int _dl_pthread_num_threads;
 struct __pthread **_dl_pthread_threads;
 int _dl_pthread_threads_lock;
+
+/* If loading a shared object requires that we make the stack executable
+   when it was not, we do it by calling this function.
+   It returns an errno code or zero on success.  */
+int (*_dl_make_stack_executable_hook) (void **) = _dl_make_stack_executable;
diff --git a/sysdeps/htl/dl-tls.c b/sysdeps/htl/dl-tls.c
new file mode 100644
index 0000000000..1ec6680c37
--- /dev/null
+++ b/sysdeps/htl/dl-tls.c
@@ -0,0 +1,39 @@ 
+/* Thread-local storage handling in the ELF dynamic linker.
+   Copyright (C) 2002-2021 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
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <elf/dl-tls.c>
+
+/* Initialize static TLS area and DTV for current (only) thread.
+   HTL provides its own hook to handle all threads.  */
+void
+_dl_nothread_init_static_tls (struct link_map *map)
+{
+#if TLS_TCB_AT_TP
+  void *dest = (char *) THREAD_SELF - map->l_tls_offset;
+#elif TLS_DTV_AT_TP
+  void *dest = (char *) THREAD_SELF + map->l_tls_offset + TLS_PRE_TCB_SIZE;
+#else
+# error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
+#endif
+
+  /* Initialize the memory.  */
+  memset (__mempcpy (dest, map->l_tls_initimage, map->l_tls_initimage_size),
+          '\0', map->l_tls_blocksize - map->l_tls_initimage_size);
+}
+
+void (*_dl_init_static_tls) (struct link_map *) = &_dl_nothread_init_static_tls;
diff --git a/elf/dl-tls_init_tp.c b/sysdeps/htl/dl-tls_init_tp.c
similarity index 93%
rename from elf/dl-tls_init_tp.c
rename to sysdeps/htl/dl-tls_init_tp.c
index d84adc992c..d0810a8e22 100644
--- a/elf/dl-tls_init_tp.c
+++ b/sysdeps/htl/dl-tls_init_tp.c
@@ -1,4 +1,4 @@ 
-/* Completion of TCB initialization after TLS_INIT_TP.  Generic version.
+/* Completion of TCB initialization after TLS_INIT_TP.
    Copyright (C) 2021 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -36,9 +36,7 @@  rtld_lock_default_unlock_recursive (void *lock)
 void
 __tls_pre_init_tp (void)
 {
-#if !THREAD_GSCOPE_IN_TCB
   GL(dl_init_static_tls) = &_dl_nothread_init_static_tls;
-#endif
 
 #if defined SHARED && defined _LIBC_REENTRANT \
     && defined __rtld_lock_default_lock_recursive
diff --git a/sysdeps/nptl/dl-support.c b/sysdeps/nptl/dl-support.c
new file mode 100644
index 0000000000..135d49b922
--- /dev/null
+++ b/sysdeps/nptl/dl-support.c
@@ -0,0 +1,26 @@ 
+/* Support for dynamic linking code in static libc.
+   Copyright (C) 2007-2021 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
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <elf/dl-support.c>
+
+list_t _dl_stack_used;
+list_t _dl_stack_user;
+list_t _dl_stack_cache;
+size_t _dl_stack_cache_actsize;
+uintptr_t _dl_in_flight_stack;
+int _dl_stack_cache_lock;
diff --git a/sysdeps/nptl/dl-tls.c b/sysdeps/nptl/dl-tls.c
new file mode 100644
index 0000000000..9e0ecfed24
--- /dev/null
+++ b/sysdeps/nptl/dl-tls.c
@@ -0,0 +1,53 @@ 
+/* Thread-local storage handling in the ELF dynamic linker.
+   Copyright (C) 2002-2021 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
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <elf/dl-tls.c>
+#include <list.h>
+
+static inline void __attribute__((always_inline))
+init_one_static_tls (struct pthread *curp, struct link_map *map)
+{
+# if TLS_TCB_AT_TP
+  void *dest = (char *) curp - map->l_tls_offset;
+# elif TLS_DTV_AT_TP
+  void *dest = (char *) curp + map->l_tls_offset + TLS_PRE_TCB_SIZE;
+# else
+#  error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
+# endif
+
+  /* Initialize the memory.  */
+  memset (__mempcpy (dest, map->l_tls_initimage, map->l_tls_initimage_size),
+          '\0', map->l_tls_blocksize - map->l_tls_initimage_size);
+}
+
+void
+_dl_init_static_tls (struct link_map *map)
+{
+  lll_lock (GL (dl_stack_cache_lock), LLL_PRIVATE);
+
+  /* Iterate over the list with system-allocated threads first.  */
+  list_t *runp;
+  list_for_each (runp, &GL (dl_stack_used))
+    init_one_static_tls (list_entry (runp, struct pthread, list), map);
+
+  /* Now the list with threads using user-allocated stacks.  */
+  list_for_each (runp, &GL (dl_stack_user))
+    init_one_static_tls (list_entry (runp, struct pthread, list), map);
+
+  lll_unlock (GL (dl_stack_cache_lock), LLL_PRIVATE);
+}
diff --git a/sysdeps/unix/sysv/linux/alpha/dl-support.c b/sysdeps/unix/sysv/linux/alpha/dl-support.c
index 290217671c..6fde3f8d9a 100644
--- a/sysdeps/unix/sysv/linux/alpha/dl-support.c
+++ b/sysdeps/unix/sysv/linux/alpha/dl-support.c
@@ -1,2 +1,2 @@ 
 #include "dl-auxv.h"
-#include <elf/dl-support.c>
+#include <sysdeps/nptl/dl-support.c>