aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/cgo
diff options
context:
space:
mode:
authorElias Naur <mail@eliasnaur.com>2019-03-29 12:13:02 +0100
committerElias Naur <mail@eliasnaur.com>2019-03-29 17:16:54 +0000
commit95f18757a0fa283c4237ca03b48049980fe9b9c3 (patch)
tree8fc7d91caa9c1986cb45183010b1c9d913332a20 /src/runtime/cgo
parent1d10b17589ce651caeb0841b2312065ee44f800d (diff)
downloadgo-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.c22
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;