summaryrefslogtreecommitdiff
path: root/libc
diff options
context:
space:
mode:
Diffstat (limited to 'libc')
-rw-r--r--libc/arch-x86/bionic/__libc_init_sysinfo.cpp7
-rw-r--r--libc/bionic/__libc_init_main_thread.cpp41
-rw-r--r--libc/bionic/bionic_arc4random.cpp6
-rw-r--r--libc/bionic/getauxval.cpp20
-rw-r--r--libc/bionic/libc_init_common.cpp10
-rw-r--r--libc/bionic/libc_init_common.h4
-rw-r--r--libc/bionic/libc_init_dynamic.cpp18
-rw-r--r--libc/bionic/libc_init_static.cpp10
-rw-r--r--libc/bionic/pthread_create.cpp36
-rw-r--r--libc/bionic/pthread_internal.h7
-rw-r--r--libc/bionic/setjmp_cookie.cpp5
-rw-r--r--libc/bionic/vdso.cpp6
-rw-r--r--libc/private/bionic_arc4random.h4
-rw-r--r--libc/private/bionic_auxv.h14
-rw-r--r--libc/private/bionic_globals.h10
-rw-r--r--libc/private/bionic_tls.h9
16 files changed, 105 insertions, 102 deletions
diff --git a/libc/arch-x86/bionic/__libc_init_sysinfo.cpp b/libc/arch-x86/bionic/__libc_init_sysinfo.cpp
index 1bb7ab073..849d253c9 100644
--- a/libc/arch-x86/bionic/__libc_init_sysinfo.cpp
+++ b/libc/arch-x86/bionic/__libc_init_sysinfo.cpp
@@ -26,14 +26,15 @@
* SUCH DAMAGE.
*/
-#include "private/KernelArgumentBlock.h"
+#include "private/bionic_auxv.h"
#include "private/bionic_globals.h"
// This file is compiled without stack protection, because it runs before TLS
// has been set up.
-__LIBC_HIDDEN__ void __libc_init_sysinfo(KernelArgumentBlock& args) {
- __libc_sysinfo = reinterpret_cast<void*>(args.getauxval(AT_SYSINFO));
+__LIBC_HIDDEN__ void __libc_init_sysinfo() {
+ bool dummy;
+ __libc_sysinfo = reinterpret_cast<void*>(__bionic_getauxval(AT_SYSINFO, dummy));
}
// TODO: lose this function and just access __libc_sysinfo directly.
diff --git a/libc/bionic/__libc_init_main_thread.cpp b/libc/bionic/__libc_init_main_thread.cpp
index be9d32ec5..5abdc0703 100644
--- a/libc/bionic/__libc_init_main_thread.cpp
+++ b/libc/bionic/__libc_init_main_thread.cpp
@@ -30,12 +30,12 @@
#include "private/KernelArgumentBlock.h"
#include "private/bionic_arc4random.h"
-#include "private/bionic_auxv.h"
#include "private/bionic_defs.h"
#include "private/bionic_globals.h"
#include "private/bionic_ssp.h"
#include "pthread_internal.h"
+extern "C" pid_t __getpid();
extern "C" int __set_tid_address(int* tid_address);
// Declared in "private/bionic_ssp.h".
@@ -61,23 +61,36 @@ pthread_internal_t* __get_main_thread() {
// -fno-stack-protector because it's responsible for setting up the main
// thread's TLS (which stack protector relies on).
+// Do enough setup to:
+// - Let the dynamic linker invoke system calls (and access errno)
+// - Ensure that TLS access functions (__get_{tls,thread}) never return NULL
+// - Allow the stack protector to work (with a zero cookie)
+// Avoid doing much more because, when this code is called within the dynamic
+// linker, the linker binary hasn't been relocated yet, so certain kinds of code
+// are hazardous, such as accessing non-hidden global variables.
__BIONIC_WEAK_FOR_NATIVE_BRIDGE
-void __libc_init_main_thread(KernelArgumentBlock& args) {
- __libc_auxv = args.auxv;
+void __libc_init_main_thread_early(KernelArgumentBlock& args) {
+ __libc_shared_globals()->auxv = args.auxv;
#if defined(__i386__)
- __libc_init_sysinfo(args);
+ __libc_init_sysinfo();
#endif
-
- // The -fstack-protector implementation uses TLS, so make sure that's
- // set up before we call any function that might get a stack check inserted.
- // TLS also needs to be set up before errno (and therefore syscalls) can be used.
__set_tls(main_thread.tls);
- if (!__init_tls(&main_thread)) async_safe_fatal("failed to initialize TLS: %s", strerror(errno));
+ __init_tls(&main_thread);
+ main_thread.tid = __getpid();
+ main_thread.set_cached_pid(main_thread.tid);
+}
+
+// Finish initializing the main thread.
+__BIONIC_WEAK_FOR_NATIVE_BRIDGE
+void __libc_init_main_thread_late() {
+ main_thread.bionic_tls = __allocate_bionic_tls();
+ if (main_thread.bionic_tls == nullptr) {
+ // Avoid strerror because it might need bionic_tls.
+ async_safe_fatal("failed to allocate bionic_tls: error %d", errno);
+ }
// Tell the kernel to clear our tid field when we exit, so we're like any other pthread.
- // As a side-effect, this tells us our pid (which is the same as the main thread's tid).
- main_thread.tid = __set_tid_address(&main_thread.tid);
- main_thread.set_cached_pid(main_thread.tid);
+ __set_tid_address(&main_thread.tid);
// 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.
@@ -96,8 +109,8 @@ void __libc_init_main_thread(KernelArgumentBlock& args) {
// The TLS stack guard is set from the global, so ensure that we've initialized the global
// before we initialize the TLS. Dynamic executables will initialize their copy of the global
// stack protector from the one in the main thread's TLS.
- __libc_safe_arc4random_buf(&__stack_chk_guard, sizeof(__stack_chk_guard), args);
- __init_thread_stack_guard(&main_thread);
+ __libc_safe_arc4random_buf(&__stack_chk_guard, sizeof(__stack_chk_guard));
+ __init_tls_stack_guard(&main_thread);
__init_thread(&main_thread);
diff --git a/libc/bionic/bionic_arc4random.cpp b/libc/bionic/bionic_arc4random.cpp
index fa2617f0d..74ac43cb2 100644
--- a/libc/bionic/bionic_arc4random.cpp
+++ b/libc/bionic/bionic_arc4random.cpp
@@ -35,9 +35,7 @@
#include <async_safe/log.h>
-#include "private/KernelArgumentBlock.h"
-
-void __libc_safe_arc4random_buf(void* buf, size_t n, KernelArgumentBlock& args) {
+void __libc_safe_arc4random_buf(void* buf, size_t n) {
// Only call arc4random_buf once we have `/dev/urandom` because getentropy(3)
// will fall back to using `/dev/urandom` if getrandom(2) fails, and abort if
// if can't use `/dev/urandom`.
@@ -53,7 +51,7 @@ void __libc_safe_arc4random_buf(void* buf, size_t n, KernelArgumentBlock& args)
16 - at_random_bytes_consumed, n);
}
- memcpy(buf, reinterpret_cast<char*>(args.getauxval(AT_RANDOM)) + at_random_bytes_consumed, n);
+ memcpy(buf, reinterpret_cast<char*>(getauxval(AT_RANDOM)) + at_random_bytes_consumed, n);
at_random_bytes_consumed += n;
return;
}
diff --git a/libc/bionic/getauxval.cpp b/libc/bionic/getauxval.cpp
index 607e89c99..c8f867b64 100644
--- a/libc/bionic/getauxval.cpp
+++ b/libc/bionic/getauxval.cpp
@@ -30,17 +30,27 @@
#include <sys/cdefs.h>
#include <sys/auxv.h>
#include <private/bionic_auxv.h>
+#include <private/bionic_globals.h>
#include <elf.h>
#include <errno.h>
-__LIBC_HIDDEN__ ElfW(auxv_t)* __libc_auxv = nullptr;
-
-extern "C" unsigned long int getauxval(unsigned long int type) {
- for (ElfW(auxv_t)* v = __libc_auxv; v->a_type != AT_NULL; ++v) {
+// This function needs to be safe to call before TLS is set up, so it can't
+// access errno or the stack protector.
+__attribute__((no_stack_protector))
+__LIBC_HIDDEN__ unsigned long __bionic_getauxval(unsigned long type, bool& exists) {
+ for (ElfW(auxv_t)* v = __libc_shared_globals()->auxv; v->a_type != AT_NULL; ++v) {
if (v->a_type == type) {
+ exists = true;
return v->a_un.a_val;
}
}
- errno = ENOENT;
+ exists = false;
return 0;
}
+
+extern "C" unsigned long getauxval(unsigned long type) {
+ bool exists;
+ unsigned long result = __bionic_getauxval(type, exists);
+ if (!exists) errno = ENOENT;
+ return result;
+}
diff --git a/libc/bionic/libc_init_common.cpp b/libc/bionic/libc_init_common.cpp
index 4702e1c9a..f1fbfa948 100644
--- a/libc/bionic/libc_init_common.cpp
+++ b/libc/bionic/libc_init_common.cpp
@@ -43,9 +43,7 @@
#include <async_safe/log.h>
-#include "private/KernelArgumentBlock.h"
#include "private/WriteProtected.h"
-#include "private/bionic_auxv.h"
#include "private/bionic_defs.h"
#include "private/bionic_globals.h"
#include "private/bionic_tls.h"
@@ -59,14 +57,14 @@ __LIBC_HIDDEN__ WriteProtected<libc_globals> __libc_globals;
// Not public, but well-known in the BSDs.
const char* __progname;
-void __libc_init_globals(KernelArgumentBlock& args) {
+void __libc_init_globals() {
// Initialize libc globals that are needed in both the linker and in libc.
// In dynamic binaries, this is run at least twice for different copies of the
// globals, once for the linker's copy and once for the one in libc.so.
__libc_globals.initialize();
- __libc_globals.mutate([&args](libc_globals* globals) {
- __libc_init_vdso(globals, args);
- __libc_init_setjmp_cookie(globals, args);
+ __libc_globals.mutate([](libc_globals* globals) {
+ __libc_init_vdso(globals);
+ __libc_init_setjmp_cookie(globals);
});
}
diff --git a/libc/bionic/libc_init_common.h b/libc/bionic/libc_init_common.h
index 84b59ca2d..73f5817cf 100644
--- a/libc/bionic/libc_init_common.h
+++ b/libc/bionic/libc_init_common.h
@@ -50,9 +50,7 @@ __END_DECLS
#if defined(__cplusplus)
-class KernelArgumentBlock;
-
-__LIBC_HIDDEN__ void __libc_init_globals(KernelArgumentBlock& args);
+__LIBC_HIDDEN__ void __libc_init_globals();
__LIBC_HIDDEN__ void __libc_init_common();
diff --git a/libc/bionic/libc_init_dynamic.cpp b/libc/bionic/libc_init_dynamic.cpp
index 25d462f8c..af1b84776 100644
--- a/libc/bionic/libc_init_dynamic.cpp
+++ b/libc/bionic/libc_init_dynamic.cpp
@@ -51,7 +51,6 @@
#include <elf.h>
#include "libc_init_common.h"
-#include "private/bionic_auxv.h"
#include "private/bionic_globals.h"
#include "private/bionic_macros.h"
#include "private/bionic_ssp.h"
@@ -78,13 +77,12 @@ __LIBC_HIDDEN__ void* __libc_sysinfo = reinterpret_cast<void*>(__libc_int0x80);
// after __stack_chk_guard is initialized and therefore can safely have a stack
// protector.
__attribute__((noinline))
-static void __libc_preinit_impl(KernelArgumentBlock& args) {
- __libc_auxv = args.auxv;
+static void __libc_preinit_impl() {
#if defined(__i386__)
- __libc_init_sysinfo(args);
+ __libc_init_sysinfo();
#endif
- __libc_init_globals(args);
+ __libc_init_globals();
__libc_init_common();
// Hooks for various libraries to let them know that we're starting up.
@@ -100,17 +98,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, then clear the slot so no
- // other initializer sees its value.
- void** tls = __get_tls();
- 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.
- __stack_chk_guard = reinterpret_cast<uintptr_t>(tls[TLS_SLOT_STACK_GUARD]);
+ __stack_chk_guard = reinterpret_cast<uintptr_t>(__get_tls()[TLS_SLOT_STACK_GUARD]);
- __libc_preinit_impl(*args);
+ __libc_preinit_impl();
}
// This function is called from the executable's _start entry point
diff --git a/libc/bionic/libc_init_static.cpp b/libc/bionic/libc_init_static.cpp
index 51fbe07bf..289b4a3c6 100644
--- a/libc/bionic/libc_init_static.cpp
+++ b/libc/bionic/libc_init_static.cpp
@@ -95,14 +95,12 @@ __noreturn static void __real_libc_init(void *raw_args,
structors_array_t const * const structors) {
BIONIC_STOP_UNWIND;
+ // Initialize TLS early so system calls and errno work.
KernelArgumentBlock args(raw_args);
+ __libc_init_main_thread_early(args);
+ __libc_init_main_thread_late();
+ __libc_init_globals();
__libc_shared_globals()->init_progname = args.argv[0];
-
- // Initializing the globals requires TLS to be available for errno.
- __libc_init_main_thread(args);
-
- __libc_init_globals(args);
-
__libc_init_AT_SECURE(args.envp);
__libc_init_common();
diff --git a/libc/bionic/pthread_create.cpp b/libc/bionic/pthread_create.cpp
index 6f632e851..8e8d180d3 100644
--- a/libc/bionic/pthread_create.cpp
+++ b/libc/bionic/pthread_create.cpp
@@ -53,39 +53,43 @@ void __init_user_desc(struct user_desc*, bool, void*);
#endif
// This code is used both by each new pthread and the code that initializes the main thread.
-bool __init_tls(pthread_internal_t* thread) {
+__attribute__((no_stack_protector))
+void __init_tls(pthread_internal_t* thread) {
// Slot 0 must point to itself. The x86 Linux kernel reads the TLS from %fs:0.
thread->tls[TLS_SLOT_SELF] = thread->tls;
thread->tls[TLS_SLOT_THREAD_ID] = thread;
+}
+__attribute__((no_stack_protector))
+void __init_tls_stack_guard(pthread_internal_t* thread) {
+ // GCC looks in the TLS for the stack guard on x86, so copy it there from our global.
+ thread->tls[TLS_SLOT_STACK_GUARD] = reinterpret_cast<void*>(__stack_chk_guard);
+}
+
+bionic_tls* __allocate_bionic_tls() {
// Add a guard before and after.
size_t allocation_size = BIONIC_TLS_SIZE + (2 * PTHREAD_GUARD_SIZE);
void* allocation = mmap(nullptr, allocation_size, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (allocation == MAP_FAILED) {
async_safe_format_log(ANDROID_LOG_WARN, "libc",
"pthread_create failed: couldn't allocate TLS: %s", strerror(errno));
- return false;
+ return nullptr;
}
prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, allocation, allocation_size, "bionic TLS guard");
// Carve out the writable TLS section.
- thread->bionic_tls = reinterpret_cast<bionic_tls*>(static_cast<char*>(allocation) +
+ bionic_tls* result = reinterpret_cast<bionic_tls*>(static_cast<char*>(allocation) +
PTHREAD_GUARD_SIZE);
- if (mprotect(thread->bionic_tls, BIONIC_TLS_SIZE, PROT_READ | PROT_WRITE) != 0) {
+ if (mprotect(result, BIONIC_TLS_SIZE, PROT_READ | PROT_WRITE) != 0) {
async_safe_format_log(ANDROID_LOG_WARN, "libc",
"pthread_create failed: couldn't mprotect TLS: %s", strerror(errno));
munmap(allocation, allocation_size);
- return false;
+ return nullptr;
}
- prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, thread->bionic_tls, BIONIC_TLS_SIZE, "bionic TLS");
- return true;
-}
-
-void __init_thread_stack_guard(pthread_internal_t* thread) {
- // GCC looks in the TLS for the stack guard on x86, so copy it there from our global.
- thread->tls[TLS_SLOT_STACK_GUARD] = reinterpret_cast<void*>(__stack_chk_guard);
+ prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, result, BIONIC_TLS_SIZE, "bionic TLS");
+ return result;
}
static void __init_alternate_signal_stack(pthread_internal_t* thread) {
@@ -255,11 +259,15 @@ static int __allocate_thread(pthread_attr_t* attr, pthread_internal_t** threadp,
thread->mmap_size = mmap_size;
thread->attr = *attr;
- if (!__init_tls(thread)) {
+
+ thread->bionic_tls = __allocate_bionic_tls();
+ if (thread->bionic_tls == nullptr) {
if (thread->mmap_size != 0) munmap(thread->attr.stack_base, thread->mmap_size);
return EAGAIN;
}
- __init_thread_stack_guard(thread);
+
+ __init_tls(thread);
+ __init_tls_stack_guard(thread);
*threadp = thread;
*child_stack = stack_top;
diff --git a/libc/bionic/pthread_internal.h b/libc/bionic/pthread_internal.h
index 81b885aac..5a5318d6b 100644
--- a/libc/bionic/pthread_internal.h
+++ b/libc/bionic/pthread_internal.h
@@ -152,10 +152,11 @@ class pthread_internal_t {
pthread_key_data_t key_data[BIONIC_PTHREAD_KEY_COUNT];
};
-__LIBC_HIDDEN__ int __init_thread(pthread_internal_t* thread);
-__LIBC_HIDDEN__ bool __init_tls(pthread_internal_t* thread);
-__LIBC_HIDDEN__ void __init_thread_stack_guard(pthread_internal_t* thread);
+__LIBC_HIDDEN__ void __init_tls(pthread_internal_t* thread);
+__LIBC_HIDDEN__ void __init_tls_stack_guard(pthread_internal_t* thread);
+__LIBC_HIDDEN__ bionic_tls* __allocate_bionic_tls();
__LIBC_HIDDEN__ void __init_additional_stacks(pthread_internal_t*);
+__LIBC_HIDDEN__ int __init_thread(pthread_internal_t* thread);
__LIBC_HIDDEN__ pthread_t __pthread_internal_add(pthread_internal_t* thread);
__LIBC_HIDDEN__ pthread_internal_t* __pthread_internal_find(pthread_t pthread_id);
diff --git a/libc/bionic/setjmp_cookie.cpp b/libc/bionic/setjmp_cookie.cpp
index 41a439feb..e2a3fc098 100644
--- a/libc/bionic/setjmp_cookie.cpp
+++ b/libc/bionic/setjmp_cookie.cpp
@@ -38,11 +38,10 @@
#include "private/bionic_arc4random.h"
#include "private/bionic_globals.h"
-#include "private/KernelArgumentBlock.h"
-void __libc_init_setjmp_cookie(libc_globals* globals, KernelArgumentBlock& args) {
+void __libc_init_setjmp_cookie(libc_globals* globals) {
long value;
- __libc_safe_arc4random_buf(&value, sizeof(value), args);
+ __libc_safe_arc4random_buf(&value, sizeof(value));
// Mask off the last bit to store the signal flag.
globals->setjmp_cookie = value & ~1;
diff --git a/libc/bionic/vdso.cpp b/libc/bionic/vdso.cpp
index c926a5806..dbca9c013 100644
--- a/libc/bionic/vdso.cpp
+++ b/libc/bionic/vdso.cpp
@@ -20,11 +20,11 @@
#include <limits.h>
#include <link.h>
#include <string.h>
+#include <sys/auxv.h>
#include <sys/cdefs.h>
#include <sys/time.h>
#include <time.h>
#include <unistd.h>
-#include "private/KernelArgumentBlock.h"
static inline int vdso_return(int result) {
if (__predict_true(result == 0)) return 0;
@@ -73,7 +73,7 @@ time_t time(time_t* t) {
return tv.tv_sec;
}
-void __libc_init_vdso(libc_globals* globals, KernelArgumentBlock& args) {
+void __libc_init_vdso(libc_globals* globals) {
auto&& vdso = globals->vdso;
vdso[VDSO_CLOCK_GETTIME] = { VDSO_CLOCK_GETTIME_SYMBOL, nullptr };
vdso[VDSO_CLOCK_GETRES] = { VDSO_CLOCK_GETRES_SYMBOL, nullptr };
@@ -81,7 +81,7 @@ void __libc_init_vdso(libc_globals* globals, KernelArgumentBlock& args) {
vdso[VDSO_TIME] = { VDSO_TIME_SYMBOL, nullptr };
// Do we have a vdso?
- uintptr_t vdso_ehdr_addr = args.getauxval(AT_SYSINFO_EHDR);
+ uintptr_t vdso_ehdr_addr = getauxval(AT_SYSINFO_EHDR);
ElfW(Ehdr)* vdso_ehdr = reinterpret_cast<ElfW(Ehdr)*>(vdso_ehdr_addr);
if (vdso_ehdr == nullptr) {
return;
diff --git a/libc/private/bionic_arc4random.h b/libc/private/bionic_arc4random.h
index 0e9376e9e..cdc9b6dc6 100644
--- a/libc/private/bionic_arc4random.h
+++ b/libc/private/bionic_arc4random.h
@@ -31,13 +31,11 @@
#include <stddef.h>
-#include "private/KernelArgumentBlock.h"
-
// arc4random(3) aborts if it's unable to fetch entropy, which is always
// the case for init on devices. GCE kernels have a workaround to ensure
// sufficient entropy during early boot, but no device kernels do. This
// wrapper falls back to AT_RANDOM if the kernel doesn't have enough
// entropy for getrandom(2) or /dev/urandom.
-void __libc_safe_arc4random_buf(void* buf, size_t n, KernelArgumentBlock& args);
+void __libc_safe_arc4random_buf(void* buf, size_t n);
#endif
diff --git a/libc/private/bionic_auxv.h b/libc/private/bionic_auxv.h
index 53fcc491b..8e33c1cf1 100644
--- a/libc/private/bionic_auxv.h
+++ b/libc/private/bionic_auxv.h
@@ -25,17 +25,9 @@
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
-#ifndef _PRIVATE_BIONIC_AUXV_H_
-#define _PRIVATE_BIONIC_AUXV_H_
-#include <elf.h>
-#include <link.h>
-#include <sys/cdefs.h>
-
-__BEGIN_DECLS
+#pragma once
-extern ElfW(auxv_t)* __libc_auxv;
-
-__END_DECLS
+#include <sys/cdefs.h>
-#endif /* _PRIVATE_BIONIC_AUXV_H_ */
+__LIBC_HIDDEN__ unsigned long __bionic_getauxval(unsigned long type, bool& exists);
diff --git a/libc/private/bionic_globals.h b/libc/private/bionic_globals.h
index 906d569d9..ba510b11d 100644
--- a/libc/private/bionic_globals.h
+++ b/libc/private/bionic_globals.h
@@ -30,6 +30,7 @@
#define _PRIVATE_BIONIC_GLOBALS_H
#include <sys/cdefs.h>
+#include <link.h>
#include <pthread.h>
#include "private/bionic_fdsan.h"
@@ -56,6 +57,8 @@ struct libc_shared_globals {
// the program it's loading. Typically 0, sometimes 1.
int initial_linker_arg_count;
+ ElfW(auxv_t)* auxv;
+
pthread_mutex_t abort_msg_lock;
abort_msg_t* abort_msg;
@@ -67,14 +70,13 @@ struct libc_shared_globals {
__LIBC_HIDDEN__ libc_shared_globals* __libc_shared_globals();
__LIBC_HIDDEN__ void __libc_init_fdsan();
-class KernelArgumentBlock;
__LIBC_HIDDEN__ void __libc_init_malloc(libc_globals* globals);
-__LIBC_HIDDEN__ void __libc_init_setjmp_cookie(libc_globals* globals, KernelArgumentBlock& args);
-__LIBC_HIDDEN__ void __libc_init_vdso(libc_globals* globals, KernelArgumentBlock& args);
+__LIBC_HIDDEN__ void __libc_init_setjmp_cookie(libc_globals* globals);
+__LIBC_HIDDEN__ void __libc_init_vdso(libc_globals* globals);
#if defined(__i386__)
__LIBC_HIDDEN__ extern void* __libc_sysinfo;
-__LIBC_HIDDEN__ void __libc_init_sysinfo(KernelArgumentBlock& args);
+__LIBC_HIDDEN__ void __libc_init_sysinfo();
#endif
#endif
diff --git a/libc/private/bionic_tls.h b/libc/private/bionic_tls.h
index de086f2d4..80dc9bce7 100644
--- a/libc/private/bionic_tls.h
+++ b/libc/private/bionic_tls.h
@@ -63,12 +63,6 @@ enum {
TLS_SLOT_OPENGL_API = 3,
TLS_SLOT_OPENGL = 4,
- // This slot is only used to pass information from the dynamic linker to
- // libc.so when the C library is loaded in to memory. The C runtime init
- // function will then clear it. Since its use is extremely temporary,
- // we reuse an existing location that isn't needed during libc startup.
- TLS_SLOT_BIONIC_PREINIT = TLS_SLOT_OPENGL_API,
-
TLS_SLOT_STACK_GUARD = 5, // GCC requires this specific slot for x86.
TLS_SLOT_DLERROR,
@@ -132,7 +126,8 @@ __END_DECLS
#if defined(__cplusplus)
class KernelArgumentBlock;
-extern void __libc_init_main_thread(KernelArgumentBlock&);
+extern void __libc_init_main_thread_early(KernelArgumentBlock& args);
+extern void __libc_init_main_thread_late();
#endif
#endif /* __BIONIC_PRIVATE_BIONIC_TLS_H_ */