elf: Introduce __tls_pre_init_tp

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.

Tested-by: Carlos O'Donell <carlos@redhat.com>
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
This commit is contained in:
Florian Weimer 2021-05-10 10:31:41 +02:00
parent 0df5d8d404
commit d017b0ab5a
6 changed files with 60 additions and 40 deletions

View File

@ -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)

View File

@ -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. */

View File

@ -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)
{

View File

@ -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. */

View File

@ -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. */

View File

@ -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_pre_init_tp (void)
{
/* 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. */
INIT_LIST_HEAD (&GL (dl_stack_used));
INIT_LIST_HEAD (&GL (dl_stack_user));
list_add (&THREAD_SELF->list, &GL (dl_stack_user));
/* Early initialization of the TCB. */