aboutsummaryrefslogtreecommitdiff
path: root/libc/bionic/pthread_internal.h
diff options
context:
space:
mode:
authorRyan Prichard <rprichard@google.com>2018-10-19 20:35:23 -0700
committerRyan Prichard <rprichard@google.com>2018-10-25 23:31:17 +0000
commit29d6dbc906f51f127700fd9e2d1e1170456f2382 (patch)
tree09bdf2be3f29c92de8ac17f8ee27691d26356640 /libc/bionic/pthread_internal.h
parenta2af8bea8c6c4b6ce6883bf92cbce922e0d9f458 (diff)
downloadbionic-29d6dbc906f51f127700fd9e2d1e1170456f2382.tar.gz
Move Bionic slots to the end of pthread_internal_t
With ELF TLS, the static linker assumes that an executable's TLS segment is at a known offset from the thread pointer (i.e. __get_tls()). The segment can be located prior to the TP (variant 2, x86[_64], sparc) or after it (variant 1, arm{32,64}, ppc, mips, ia64, riscv). We can't make our pthread_internal_t exactly follow the ordinary arm64 ABI (at least) because TP[5] is used for clang's -fstack-protector on Android. Instead, reserve extra space after the TP (up to 16 words), which will be followed by the executable's TLS segment. Bug: http://b/78026329 Test: boot device, bionic unit tests Change-Id: I0f3b270b793f9872ba0effeac03f4dec364438d6 Merged-In: I0f3b270b793f9872ba0effeac03f4dec364438d6 (cherry picked from commit f397317e96928ef24b980d5c73d08829c0e70cd4)
Diffstat (limited to 'libc/bionic/pthread_internal.h')
-rw-r--r--libc/bionic/pthread_internal.h10
1 files changed, 6 insertions, 4 deletions
diff --git a/libc/bionic/pthread_internal.h b/libc/bionic/pthread_internal.h
index 65ec5ff2b..b68cb942f 100644
--- a/libc/bionic/pthread_internal.h
+++ b/libc/bionic/pthread_internal.h
@@ -112,10 +112,6 @@ class pthread_internal_t {
thread_local_dtor* thread_local_dtors;
- void* tls[BIONIC_TLS_SLOTS];
-
- pthread_key_data_t key_data[BIONIC_PTHREAD_KEY_COUNT];
-
/*
* The dynamic linker implements dlerror(3), which makes it hard for us to implement this
* per-thread buffer by simply using malloc(3) and free(3).
@@ -124,6 +120,12 @@ class pthread_internal_t {
char dlerror_buffer[__BIONIC_DLERROR_BUFFER_SIZE];
bionic_tls* bionic_tls;
+
+ pthread_key_data_t key_data[BIONIC_PTHREAD_KEY_COUNT];
+
+ // The thread pointer (__get_tls()) points at this field. This field must come last so that
+ // an executable's TLS segment can be allocated at a fixed offset after the thread pointer.
+ void* tls[BIONIC_TLS_SLOTS];
};
__LIBC_HIDDEN__ int __init_thread(pthread_internal_t* thread);