1
0
mirror of https://github.com/golang/go synced 2024-11-24 04:50:07 -07:00

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>
This commit is contained in:
Elias Naur 2019-03-29 12:13:02 +01:00
parent 1d10b17589
commit 95f18757a0

View File

@ -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;