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:
parent
0df5d8d404
commit
d017b0ab5a
|
@ -114,6 +114,8 @@ __libc_setup_tls (void)
|
||||||
|
|
||||||
struct link_map *main_map = GL(dl_ns)[LM_ID_BASE]._ns_loaded;
|
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. */
|
/* Look through the TLS segment if there is any. */
|
||||||
if (_dl_phdr != NULL)
|
if (_dl_phdr != NULL)
|
||||||
for (phdr = _dl_phdr; phdr < &_dl_phdr[_dl_phnum]; ++phdr)
|
for (phdr = _dl_phdr; phdr < &_dl_phdr[_dl_phnum]; ++phdr)
|
||||||
|
|
|
@ -16,4 +16,4 @@
|
||||||
License along with the GNU C Library; if not, see
|
License along with the GNU C Library; if not, see
|
||||||
<https://www.gnu.org/licenses/>. */
|
<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. */
|
||||||
|
|
|
@ -18,6 +18,35 @@
|
||||||
|
|
||||||
#include <ldsodefs.h>
|
#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
|
void
|
||||||
__tls_init_tp (void)
|
__tls_init_tp (void)
|
||||||
{
|
{
|
||||||
|
|
38
elf/rtld.c
38
elf/rtld.c
|
@ -843,30 +843,6 @@ ERROR: ld.so: object '%s' from %s cannot be preloaded (%s): ignored.\n",
|
||||||
return 0;
|
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
|
static void
|
||||||
security_init (void)
|
security_init (void)
|
||||||
{
|
{
|
||||||
|
@ -1147,19 +1123,7 @@ dl_main (const ElfW(Phdr) *phdr,
|
||||||
struct dl_main_state state;
|
struct dl_main_state state;
|
||||||
dl_main_state_init (&state);
|
dl_main_state_init (&state);
|
||||||
|
|
||||||
#if !THREAD_GSCOPE_IN_TCB
|
__tls_pre_init_tp ();
|
||||||
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
|
|
||||||
|
|
||||||
/* The explicit initialization here is cheaper than processing the reloc
|
/* The explicit initialization here is cheaper than processing the reloc
|
||||||
in the _rtld_local definition's initializer. */
|
in the _rtld_local definition's initializer. */
|
||||||
|
|
|
@ -1165,6 +1165,10 @@ extern void _dl_determine_tlsoffset (void) attribute_hidden;
|
||||||
number of audit modules are loaded. */
|
number of audit modules are loaded. */
|
||||||
void _dl_tls_static_surplus_init (size_t naudit) attribute_hidden;
|
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
|
/* This function is called after processor-specific initialization of
|
||||||
the TCB and thread pointer via TLS_INIT_TP, to complete very early
|
the TCB and thread pointer via TLS_INIT_TP, to complete very early
|
||||||
initialization of the thread library. */
|
initialization of the thread library. */
|
||||||
|
|
|
@ -27,12 +27,33 @@ bool __nptl_set_robust_list_avail __attribute__ ((nocommon));
|
||||||
rtld_hidden_data_def (__nptl_set_robust_list_avail)
|
rtld_hidden_data_def (__nptl_set_robust_list_avail)
|
||||||
#endif
|
#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
|
void
|
||||||
__tls_init_tp (void)
|
__tls_init_tp (void)
|
||||||
{
|
{
|
||||||
/* Set up thread stack list management. */
|
/* 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));
|
list_add (&THREAD_SELF->list, &GL (dl_stack_user));
|
||||||
|
|
||||||
/* Early initialization of the TCB. */
|
/* Early initialization of the TCB. */
|
||||||
|
|
Loading…
Reference in a new issue