summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libc/private/bionic_tls.h7
-rw-r--r--linker/linker.c21
2 files changed, 21 insertions, 7 deletions
diff --git a/libc/private/bionic_tls.h b/libc/private/bionic_tls.h
index da34344..82c8cd9 100644
--- a/libc/private/bionic_tls.h
+++ b/libc/private/bionic_tls.h
@@ -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.
diff --git a/linker/linker.c b/linker/linker.c
index 77f995e..e235498 100644
--- a/linker/linker.c
+++ b/linker/linker.c
@@ -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();