[07/13] elf: Introduce __tls_pre_init_tp

Message ID 34f3a445c6c083b135bef0e147ebf994082bcb42.1620323953.git.fweimer@redhat.com
State New
Headers show
Series
  • Linux: Move most stack management out of libpthread
Related show

Commit Message

Mark Brown via Libc-alpha May 6, 2021, 6:10 p.m.
This is an early variant of __tls_init_tp, primarily for initializing
thread-related elements of _rtld_global/GL.

Some existing initialization code not needed for NPTL is moved into
the generic version of this function.
---
 csu/libc-tls.c                |  2 ++
 elf/dl-mutex.c                |  2 +-
 elf/dl-tls_init_tp.c          | 29 ++++++++++++++++++++++++++
 elf/rtld.c                    | 38 +----------------------------------
 sysdeps/generic/ldsodefs.h    |  4 ++++
 sysdeps/nptl/dl-tls_init_tp.c | 25 +++++++++++++++++++++--
 6 files changed, 60 insertions(+), 40 deletions(-)

-- 
2.30.2

Comments

Mark Brown via Libc-alpha May 9, 2021, 9:42 p.m. | #1
On 5/6/21 2:10 PM, Florian Weimer via Libc-alpha wrote:
> This is an early variant of __tls_init_tp, primarily for initializing

> thread-related elements of _rtld_global/GL.

> 

> Some existing initialization code not needed for NPTL is moved into

> the generic version of this function.


LGTM.

Tested on x86_64 and i686 without regression.

Tested-by: Carlos O'Donell <carlos@redhat.com>

Reviewed-by: Carlos O'Donell <carlos@redhat.com>


> ---

>  csu/libc-tls.c                |  2 ++

>  elf/dl-mutex.c                |  2 +-

>  elf/dl-tls_init_tp.c          | 29 ++++++++++++++++++++++++++

>  elf/rtld.c                    | 38 +----------------------------------

>  sysdeps/generic/ldsodefs.h    |  4 ++++

>  sysdeps/nptl/dl-tls_init_tp.c | 25 +++++++++++++++++++++--

>  6 files changed, 60 insertions(+), 40 deletions(-)

> 

> diff --git a/csu/libc-tls.c b/csu/libc-tls.c

> index 22f8e4838d..5515204863 100644

> --- a/csu/libc-tls.c

> +++ b/csu/libc-tls.c

> @@ -114,6 +114,8 @@ __libc_setup_tls (void)

>  

>    struct link_map *main_map = GL(dl_ns)[LM_ID_BASE]._ns_loaded;

>  

> +  __tls_pre_init_tp ();

> +

>    /* Look through the TLS segment if there is any.  */

>    if (_dl_phdr != NULL)

>      for (phdr = _dl_phdr; phdr < &_dl_phdr[_dl_phnum]; ++phdr)

> diff --git a/elf/dl-mutex.c b/elf/dl-mutex.c

> index 2cd9d49c2e..ae1d8a84f0 100644

> --- a/elf/dl-mutex.c

> +++ b/elf/dl-mutex.c

> @@ -16,4 +16,4 @@

>     License along with the GNU C Library; if not, see

>     <https://www.gnu.org/licenses/>.  */

>  

> -/* The generic version initialization happpens in dl_main.  */

> +/* Initialization happens in __tls_pre_init_tp in dl-tls_init_tp.c.  */

> diff --git a/elf/dl-tls_init_tp.c b/elf/dl-tls_init_tp.c

> index 728cd84c00..d84adc992c 100644

> --- a/elf/dl-tls_init_tp.c

> +++ b/elf/dl-tls_init_tp.c

> @@ -18,6 +18,35 @@

>  

>  #include <ldsodefs.h>

>  

> +#if defined SHARED && defined _LIBC_REENTRANT \

> +    && defined __rtld_lock_default_lock_recursive

> +static void

> +rtld_lock_default_lock_recursive (void *lock)

> +{

> +  __rtld_lock_default_lock_recursive (lock);

> +}

> +

> +static void

> +rtld_lock_default_unlock_recursive (void *lock)

> +{

> +  __rtld_lock_default_unlock_recursive (lock);

> +}

> +#endif

> +

> +void

> +__tls_pre_init_tp (void)

> +{

> +#if !THREAD_GSCOPE_IN_TCB

> +  GL(dl_init_static_tls) = &_dl_nothread_init_static_tls;


OK.

> +#endif

> +

> +#if defined SHARED && defined _LIBC_REENTRANT \

> +    && defined __rtld_lock_default_lock_recursive

> +  GL(dl_rtld_lock_recursive) = rtld_lock_default_lock_recursive;

> +  GL(dl_rtld_unlock_recursive) = rtld_lock_default_unlock_recursive;

> +#endif

> +}

> +

>  void

>  __tls_init_tp (void)

>  {

> diff --git a/elf/rtld.c b/elf/rtld.c

> index a359167f8a..1255d5cc7d 100644

> --- a/elf/rtld.c

> +++ b/elf/rtld.c

> @@ -843,30 +843,6 @@ ERROR: ld.so: object '%s' from %s cannot be preloaded (%s): ignored.\n",

>    return 0;

>  }

>  

> -#if defined SHARED && defined _LIBC_REENTRANT \

> -    && defined __rtld_lock_default_lock_recursive

> -static void

> -rtld_lock_default_lock_recursive (void *lock)

> -{

> -  __rtld_lock_default_lock_recursive (lock);

> -}

> -

> -static void

> -rtld_lock_default_unlock_recursive (void *lock)

> -{

> -  __rtld_lock_default_unlock_recursive (lock);

> -}

> -#endif

> -#if PTHREAD_IN_LIBC

> -/* Dummy implementation.  See __rtld_mutex_init.  */

> -static int

> -rtld_mutex_dummy (pthread_mutex_t *lock)

> -{

> -  return 0;

> -}

> -#endif

> -

> -

>  static void

>  security_init (void)

>  {

> @@ -1147,19 +1123,7 @@ dl_main (const ElfW(Phdr) *phdr,

>    struct dl_main_state state;

>    dl_main_state_init (&state);

>  

> -#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

> -  GL(dl_rtld_lock_recursive) = rtld_lock_default_lock_recursive;

> -  GL(dl_rtld_unlock_recursive) = rtld_lock_default_unlock_recursive;

> -#endif

> -#if PTHREAD_IN_LIBC

> -  ___rtld_mutex_lock = rtld_mutex_dummy;

> -  ___rtld_mutex_unlock = rtld_mutex_dummy;

> -#endif

> +  __tls_pre_init_tp ();

>  

>    /* The explicit initialization here is cheaper than processing the reloc

>       in the _rtld_local definition's initializer.  */

> diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h

> index 6d590d1335..ee851ac789 100644

> --- a/sysdeps/generic/ldsodefs.h

> +++ b/sysdeps/generic/ldsodefs.h

> @@ -1165,6 +1165,10 @@ extern void _dl_determine_tlsoffset (void) attribute_hidden;

>     number of audit modules are loaded.  */

>  void _dl_tls_static_surplus_init (size_t naudit) attribute_hidden;

>  

> +/* This function is called very early from dl_main to set up TLS and

> +   other thread-related data structures.  */

> +void __tls_pre_init_tp (void) attribute_hidden;

> +

>  /* This function is called after processor-specific initialization of

>     the TCB and thread pointer via TLS_INIT_TP, to complete very early

>     initialization of the thread library.  */

> diff --git a/sysdeps/nptl/dl-tls_init_tp.c b/sysdeps/nptl/dl-tls_init_tp.c

> index 05d2b6cfcc..cb29222727 100644

> --- a/sysdeps/nptl/dl-tls_init_tp.c

> +++ b/sysdeps/nptl/dl-tls_init_tp.c

> @@ -27,12 +27,33 @@ bool __nptl_set_robust_list_avail __attribute__ ((nocommon));

>  rtld_hidden_data_def (__nptl_set_robust_list_avail)

>  #endif

>  

> +#ifdef SHARED

> +/* Dummy implementation.  See __rtld_mutex_init.  */

> +static int

> +rtld_mutex_dummy (pthread_mutex_t *lock)

> +{

> +  return 0;

> +}

> +#endif

> +

>  void

> -__tls_init_tp (void)

> +__tls_pre_init_tp (void)

>  {

> -  /* Set up thread stack list management.  */

> +  /* The list data structures are not consistent until

> +     initialized.  */

>    INIT_LIST_HEAD (&GL (dl_stack_used));

>    INIT_LIST_HEAD (&GL (dl_stack_user));

> +

> +#ifdef SHARED

> +  ___rtld_mutex_lock = rtld_mutex_dummy;

> +  ___rtld_mutex_unlock = rtld_mutex_dummy;

> +#endif

> +}

> +

> +void

> +__tls_init_tp (void)

> +{

> +  /* Set up thread stack list management.  */

>    list_add (&THREAD_SELF->list, &GL (dl_stack_user));

>  

>     /* Early initialization of the TCB.   */

> 



-- 
Cheers,
Carlos.

Patch

diff --git a/csu/libc-tls.c b/csu/libc-tls.c
index 22f8e4838d..5515204863 100644
--- a/csu/libc-tls.c
+++ b/csu/libc-tls.c
@@ -114,6 +114,8 @@  __libc_setup_tls (void)
 
   struct link_map *main_map = GL(dl_ns)[LM_ID_BASE]._ns_loaded;
 
+  __tls_pre_init_tp ();
+
   /* Look through the TLS segment if there is any.  */
   if (_dl_phdr != NULL)
     for (phdr = _dl_phdr; phdr < &_dl_phdr[_dl_phnum]; ++phdr)
diff --git a/elf/dl-mutex.c b/elf/dl-mutex.c
index 2cd9d49c2e..ae1d8a84f0 100644
--- a/elf/dl-mutex.c
+++ b/elf/dl-mutex.c
@@ -16,4 +16,4 @@ 
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-/* The generic version initialization happpens in dl_main.  */
+/* Initialization happens in __tls_pre_init_tp in dl-tls_init_tp.c.  */
diff --git a/elf/dl-tls_init_tp.c b/elf/dl-tls_init_tp.c
index 728cd84c00..d84adc992c 100644
--- a/elf/dl-tls_init_tp.c
+++ b/elf/dl-tls_init_tp.c
@@ -18,6 +18,35 @@ 
 
 #include <ldsodefs.h>
 
+#if defined SHARED && defined _LIBC_REENTRANT \
+    && defined __rtld_lock_default_lock_recursive
+static void
+rtld_lock_default_lock_recursive (void *lock)
+{
+  __rtld_lock_default_lock_recursive (lock);
+}
+
+static void
+rtld_lock_default_unlock_recursive (void *lock)
+{
+  __rtld_lock_default_unlock_recursive (lock);
+}
+#endif
+
+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
+  GL(dl_rtld_lock_recursive) = rtld_lock_default_lock_recursive;
+  GL(dl_rtld_unlock_recursive) = rtld_lock_default_unlock_recursive;
+#endif
+}
+
 void
 __tls_init_tp (void)
 {
diff --git a/elf/rtld.c b/elf/rtld.c
index a359167f8a..1255d5cc7d 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -843,30 +843,6 @@  ERROR: ld.so: object '%s' from %s cannot be preloaded (%s): ignored.\n",
   return 0;
 }
 
-#if defined SHARED && defined _LIBC_REENTRANT \
-    && defined __rtld_lock_default_lock_recursive
-static void
-rtld_lock_default_lock_recursive (void *lock)
-{
-  __rtld_lock_default_lock_recursive (lock);
-}
-
-static void
-rtld_lock_default_unlock_recursive (void *lock)
-{
-  __rtld_lock_default_unlock_recursive (lock);
-}
-#endif
-#if PTHREAD_IN_LIBC
-/* Dummy implementation.  See __rtld_mutex_init.  */
-static int
-rtld_mutex_dummy (pthread_mutex_t *lock)
-{
-  return 0;
-}
-#endif
-
-
 static void
 security_init (void)
 {
@@ -1147,19 +1123,7 @@  dl_main (const ElfW(Phdr) *phdr,
   struct dl_main_state state;
   dl_main_state_init (&state);
 
-#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
-  GL(dl_rtld_lock_recursive) = rtld_lock_default_lock_recursive;
-  GL(dl_rtld_unlock_recursive) = rtld_lock_default_unlock_recursive;
-#endif
-#if PTHREAD_IN_LIBC
-  ___rtld_mutex_lock = rtld_mutex_dummy;
-  ___rtld_mutex_unlock = rtld_mutex_dummy;
-#endif
+  __tls_pre_init_tp ();
 
   /* The explicit initialization here is cheaper than processing the reloc
      in the _rtld_local definition's initializer.  */
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
index 6d590d1335..ee851ac789 100644
--- a/sysdeps/generic/ldsodefs.h
+++ b/sysdeps/generic/ldsodefs.h
@@ -1165,6 +1165,10 @@  extern void _dl_determine_tlsoffset (void) attribute_hidden;
    number of audit modules are loaded.  */
 void _dl_tls_static_surplus_init (size_t naudit) attribute_hidden;
 
+/* This function is called very early from dl_main to set up TLS and
+   other thread-related data structures.  */
+void __tls_pre_init_tp (void) attribute_hidden;
+
 /* This function is called after processor-specific initialization of
    the TCB and thread pointer via TLS_INIT_TP, to complete very early
    initialization of the thread library.  */
diff --git a/sysdeps/nptl/dl-tls_init_tp.c b/sysdeps/nptl/dl-tls_init_tp.c
index 05d2b6cfcc..cb29222727 100644
--- a/sysdeps/nptl/dl-tls_init_tp.c
+++ b/sysdeps/nptl/dl-tls_init_tp.c
@@ -27,12 +27,33 @@  bool __nptl_set_robust_list_avail __attribute__ ((nocommon));
 rtld_hidden_data_def (__nptl_set_robust_list_avail)
 #endif
 
+#ifdef SHARED
+/* Dummy implementation.  See __rtld_mutex_init.  */
+static int
+rtld_mutex_dummy (pthread_mutex_t *lock)
+{
+  return 0;
+}
+#endif
+
 void
-__tls_init_tp (void)
+__tls_pre_init_tp (void)
 {
-  /* Set up thread stack list management.  */
+  /* The list data structures are not consistent until
+     initialized.  */
   INIT_LIST_HEAD (&GL (dl_stack_used));
   INIT_LIST_HEAD (&GL (dl_stack_user));
+
+#ifdef SHARED
+  ___rtld_mutex_lock = rtld_mutex_dummy;
+  ___rtld_mutex_unlock = rtld_mutex_dummy;
+#endif
+}
+
+void
+__tls_init_tp (void)
+{
+  /* Set up thread stack list management.  */
   list_add (&THREAD_SELF->list, &GL (dl_stack_user));
 
    /* Early initialization of the TCB.   */