Initialize TLS before any application code is run.
Since e19d702b8e
, dlsym and friends use recursive mutexes that
require the current thread id, which is not available before the libc
constructor. This prevents us from using dlsym() in .preinit_array.
This change moves TLS initialization from libc constructor to the earliest
possible point - immediately after linker itself is relocated. As a result,
pthread_internal_t for the initial thread is available from the start.
As a bonus, values stored in TLS in .preinit_array are not lost when libc is
initialized.
Change-Id: Iee5a710ee000173bff63e924adeb4a4c600c1e2d
This commit is contained in:
@@ -2054,10 +2054,6 @@ static void parse_preloads(const char *path, char *delim)
|
||||
}
|
||||
}
|
||||
|
||||
#define ANDROID_TLS_SLOTS BIONIC_TLS_SLOTS
|
||||
|
||||
static void * __tls_area[ANDROID_TLS_SLOTS];
|
||||
|
||||
/*
|
||||
* This code is called after the linker has linked itself and
|
||||
* fixed it's own GOT. It is safe to make references to externs
|
||||
@@ -2076,18 +2072,6 @@ static unsigned __linker_init_post_relocation(unsigned **elfdata)
|
||||
const char *ldpath_env = NULL;
|
||||
const char *ldpreload_env = NULL;
|
||||
|
||||
/* Setup a temporary TLS area that is used to get a working
|
||||
* errno for system calls.
|
||||
*/
|
||||
__set_tls(__tls_area);
|
||||
|
||||
pid = getpid();
|
||||
|
||||
#if TIMING
|
||||
struct timeval t0, t1;
|
||||
gettimeofday(&t0, 0);
|
||||
#endif
|
||||
|
||||
/* NOTE: we store the elfdata pointer on a special location
|
||||
* of the temporary TLS area in order to pass it to
|
||||
* the C Library's runtime initializer.
|
||||
@@ -2096,7 +2080,14 @@ static unsigned __linker_init_post_relocation(unsigned **elfdata)
|
||||
* to point to a different location to ensure that no other
|
||||
* shared library constructor can access it.
|
||||
*/
|
||||
__tls_area[TLS_SLOT_BIONIC_PREINIT] = elfdata;
|
||||
__libc_init_tls(elfdata);
|
||||
|
||||
pid = getpid();
|
||||
|
||||
#if TIMING
|
||||
struct timeval t0, t1;
|
||||
gettimeofday(&t0, 0);
|
||||
#endif
|
||||
|
||||
/* Initialize environment functions, and get to the ELF aux vectors table */
|
||||
vecs = linker_env_init(vecs);
|
||||
|
Reference in New Issue
Block a user