From 95f18757a0fa283c4237ca03b48049980fe9b9c3 Mon Sep 17 00:00:00 2001 From: Elias Naur Date: Fri, 29 Mar 2019 12:13:02 +0100 Subject: [PATCH] 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 Reviewed-by: Cherry Zhang Reviewed-by: Ian Lance Taylor --- src/runtime/cgo/gcc_android.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) 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 #include #include +#include #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; -- 2.48.1