diff options
author | Elias Naur <mail@eliasnaur.com> | 2019-03-29 12:13:02 +0100 |
---|---|---|
committer | Elias Naur <mail@eliasnaur.com> | 2019-03-29 17:16:54 +0000 |
commit | 95f18757a0fa283c4237ca03b48049980fe9b9c3 (patch) | |
tree | 8fc7d91caa9c1986cb45183010b1c9d913332a20 /src/runtime/cgo | |
parent | 1d10b17589ce651caeb0841b2312065ee44f800d (diff) | |
download | go-95f18757a0fa283c4237ca03b48049980fe9b9c3.tar.gz go-95f18757a0fa283c4237ca03b48049980fe9b9c3.zip |
runtime/cgo: use free TLS slot on Android Q
Android assumes pthread tls keys correspond to some offset from the
TLS base. This is about to change in a future version of Android.
Fortunately, Android Q leaves a slot open for use to use, TLS_SLOT_APP.
Fixes #29674
Change-Id: Id6ba19afacdfed9b262453714715435e2544185f
Reviewed-on: https://go-review.googlesource.com/c/go/+/170117
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Diffstat (limited to 'src/runtime/cgo')
-rw-r--r-- | src/runtime/cgo/gcc_android.c | 22 |
1 files changed, 21 insertions, 1 deletions
diff --git a/src/runtime/cgo/gcc_android.c b/src/runtime/cgo/gcc_android.c index 44bd550a7c..a626cd0681 100644 --- a/src/runtime/cgo/gcc_android.c +++ b/src/runtime/cgo/gcc_android.c @@ -5,6 +5,7 @@ #include <stdarg.h> #include <android/log.h> #include <pthread.h> +#include <dlfcn.h> #include "libcgo.h" void @@ -34,6 +35,9 @@ fatalf(const char* format, ...) // Truncated to a different magic value on 32-bit; that's ok. #define magic1 (0x23581321345589ULL) +// From https://android.googlesource.com/platform/bionic/+/refs/heads/master/libc/private/bionic_asm_tls.h#69. +#define TLS_SLOT_APP 2 + // inittls allocates a thread-local storage slot for g. // // It finds the first available slot using pthread_key_create and uses @@ -43,6 +47,22 @@ inittls(void **tlsg, void **tlsbase) { pthread_key_t k; int i, err; + void *handle, *get_ver; + + // Check for Android Q where we can use the free TLS_SLOT_APP slot. + handle = dlopen(NULL, RTLD_LAZY); + if (handle == NULL) { + fatalf("inittls: failed to dlopen main program"); + return; + } + // android_get_device_api_level is introduced in Android Q, so its mere presence + // is enough. + get_ver = dlsym(handle, "android_get_device_api_level"); + dlclose(handle); + if (get_ver != NULL) { + *tlsg = (void *)(TLS_SLOT_APP*sizeof(void *)); + return; + } err = pthread_key_create(&k, nil); if(err != 0) { @@ -60,7 +80,7 @@ inittls(void **tlsg, void **tlsbase) return; } } - fatalf("could not find pthread key"); + fatalf("inittls: could not find pthread key"); } void (*x_cgo_inittls)(void **tlsg, void **tlsbase) = inittls; |