Pass the elfdata pointer in a slot of the temporary TLS area.

This is needed to properly initialize the C runtime when libc.so
is loaded by the dynamic linker.

Move the temporary TLS setup before the first system call, just
in case something really horrible happens, we won't crash when
trying to write an error code in 'errno'

Remove the broken TLS_SLOT_THREAD_ID setup. First, this slot
should normally receive the address of a pthread_internal_t,
not a kernel thread identifier. Second, it is never used by
the linker anyway.

Also remove an obsolete comment.
This commit is contained in:
David 'Digit' Turner 2009-07-17 17:55:01 +02:00
parent 348065586a
commit ef0bd18570
2 changed files with 21 additions and 7 deletions

View File

@ -60,6 +60,13 @@ __BEGIN_DECLS
#define TLS_SLOT_OPENGL_API 3
#define 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.
*/
#define TLS_SLOT_BIONIC_PREINIT (TLS_SLOT_ERRNO+1)
/* small technical note: it is not possible to call pthread_setspecific
* on keys that are <= TLS_SLOT_MAX_WELL_KNOWN, which is why it is set to
* TLS_SLOT_ERRNO.

View File

@ -76,11 +76,6 @@
* headers provide versions that are negative...
* - allocate space for soinfo structs dynamically instead of
* having a hard limit (64)
*
* features to add someday:
*
* - dlopen() and friends
*
*/
@ -1744,6 +1739,11 @@ unsigned __linker_init(unsigned **elfdata)
struct link_map * map;
char *ldpath_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
@ -1751,8 +1751,15 @@ unsigned __linker_init(unsigned **elfdata)
gettimeofday(&t0, 0);
#endif
__set_tls(__tls_area);
((unsigned *)__get_tls())[TLS_SLOT_THREAD_ID] = gettid();
/* 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.
*
* The initializer must clear the slot and reset the TLS
* to point to a different location to ensure that no other
* shared library constructor can access it.
*/
__tls_area[TLS_SLOT_BIONIC_PREINIT] = elfdata;
debugger_init();