Clean up TLS_SLOT_BIONIC_PREINIT usage a bit
- It is only needed for dynamic executables, so move the initialization out of __libc_init_main_thread and just before the solib constructor calls. For static executables, the slot was initialized, then never used or cleared. Instead, leave it clear. - For static executables, __libc_init_main_thread already initialized the stack guard, so remove the redundant __init_thread_stack_guard call. - Simplify the slot access/clearing a bit in __libc_preinit. - Remove the "__libc_init_common() will change the TLS area so the old one won't be accessible anyway." comment. AFAICT, it's incorrect -- the main thread's TLS area in a dynamic executable is initialized to a static pthread_internal_t object in the linker, then reused by libc.so. Test: adb shell /data/nativetest/bionic-unit-tests/bionic-unit-tests Test: adb shell /data/nativetest/bionic-unit-tests-static/bionic-unit-tests-static Change-Id: Ie2da6f5be3ad563fa65b38eaadf8ba6ecc6a64b6
This commit is contained in:
parent
aa922bbaf3
commit
6631f9b03d
|
@ -81,8 +81,7 @@ void __libc_init_main_thread(KernelArgumentBlock& args) {
|
|||
|
||||
// We don't want to free the main thread's stack even when the main thread exits
|
||||
// because things like environment variables with global scope live on it.
|
||||
// We also can't free the pthread_internal_t itself, since that lives on the main
|
||||
// thread's stack rather than on the heap.
|
||||
// We also can't free the pthread_internal_t itself, since it is a static variable.
|
||||
// The main thread has no mmap allocated space for stack or pthread_internal_t.
|
||||
main_thread.mmap_size = 0;
|
||||
|
||||
|
@ -102,9 +101,5 @@ void __libc_init_main_thread(KernelArgumentBlock& args) {
|
|||
|
||||
__init_thread(&main_thread);
|
||||
|
||||
// Store a pointer to the kernel argument block in a TLS slot to be
|
||||
// picked up by the libc constructor.
|
||||
main_thread.tls[TLS_SLOT_BIONIC_PREINIT] = &args;
|
||||
|
||||
__init_alternate_signal_stack(&main_thread);
|
||||
}
|
||||
|
|
|
@ -85,14 +85,11 @@ static void __libc_preinit_impl(KernelArgumentBlock& args) {
|
|||
// to run before any others (such as the jemalloc constructor), and lower
|
||||
// is better (http://b/68046352).
|
||||
__attribute__((constructor(1))) static void __libc_preinit() {
|
||||
// Read the kernel argument block pointer from TLS.
|
||||
// Read the kernel argument block pointer from TLS, then clear the slot so no
|
||||
// other initializer sees its value.
|
||||
void** tls = __get_tls();
|
||||
KernelArgumentBlock** args_slot = &reinterpret_cast<KernelArgumentBlock**>(tls)[TLS_SLOT_BIONIC_PREINIT];
|
||||
KernelArgumentBlock* args = *args_slot;
|
||||
|
||||
// Clear the slot so no other initializer sees its value.
|
||||
// __libc_init_common() will change the TLS area so the old one won't be accessible anyway.
|
||||
*args_slot = NULL;
|
||||
KernelArgumentBlock* args = static_cast<KernelArgumentBlock*>(tls[TLS_SLOT_BIONIC_PREINIT]);
|
||||
tls[TLS_SLOT_BIONIC_PREINIT] = nullptr;
|
||||
|
||||
// The linker has initialized its copy of the global stack_chk_guard, and filled in the main
|
||||
// thread's TLS slot with that value. Initialize the local global stack guard with its value.
|
||||
|
@ -102,9 +99,8 @@ __attribute__((constructor(1))) static void __libc_preinit() {
|
|||
}
|
||||
|
||||
// This function is called from the executable's _start entry point
|
||||
// (see arch-$ARCH/bionic/crtbegin_dynamic.S), which is itself
|
||||
// called by the dynamic linker after it has loaded all shared
|
||||
// libraries the executable depends on.
|
||||
// (see arch-$ARCH/bionic/crtbegin.c), which is itself called by the dynamic
|
||||
// linker after it has loaded all shared libraries the executable depends on.
|
||||
//
|
||||
// Note that the dynamic linker has also run all constructors in the
|
||||
// executable at this point.
|
||||
|
|
|
@ -86,10 +86,9 @@ __noreturn void __libc_init(void* raw_args,
|
|||
BIONIC_STOP_UNWIND;
|
||||
|
||||
KernelArgumentBlock args(raw_args);
|
||||
__libc_init_main_thread(args);
|
||||
|
||||
// Initializing the globals requires TLS to be available for errno.
|
||||
__init_thread_stack_guard(__get_thread());
|
||||
__libc_init_main_thread(args);
|
||||
__libc_init_globals(args);
|
||||
|
||||
__libc_init_AT_SECURE(args);
|
||||
|
|
|
@ -414,6 +414,10 @@ static ElfW(Addr) __linker_init_post_relocation(KernelArgumentBlock& args) {
|
|||
|
||||
if (!get_cfi_shadow()->InitialLinkDone(solist)) __linker_cannot_link(g_argv[0]);
|
||||
|
||||
// Store a pointer to the kernel argument block in a TLS slot to be
|
||||
// picked up by the libc constructor.
|
||||
__get_tls()[TLS_SLOT_BIONIC_PREINIT] = &args;
|
||||
|
||||
si->call_pre_init_constructors();
|
||||
|
||||
/* After the prelink_image, the si->load_bias is initialized.
|
||||
|
|
Loading…
Reference in New Issue