| | |
| | |
| | |
| |
|
| | #include <stdarg.h> |
| | #include <android/log.h> |
| | #include <pthread.h> |
| | #include <dlfcn.h> |
| | #include "libcgo.h" |
| |
|
| | void |
| | fatalf(const char* format, ...) |
| | { |
| | va_list ap; |
| |
|
| | |
| | |
| | |
| | |
| | |
| |
|
| | fprintf(stderr, "runtime/cgo: "); |
| | va_start(ap, format); |
| | vfprintf(stderr, format, ap); |
| | va_end(ap); |
| | fprintf(stderr, "\n"); |
| |
|
| | va_start(ap, format); |
| | __android_log_vprint(ANDROID_LOG_FATAL, "runtime/cgo", format, ap); |
| | va_end(ap); |
| |
|
| | abort(); |
| | } |
| |
|
| | |
| | #define magic1 (0x23581321345589ULL) |
| |
|
| | |
| | #define TLS_SLOT_APP 2 |
| |
|
| | |
| | |
| | |
| | |
| | static void |
| | inittls(void **tlsg, void **tlsbase) |
| | { |
| | pthread_key_t k; |
| | int i, err; |
| | void *handle, *get_ver, *off; |
| |
|
| | |
| | handle = dlopen("libc.so", RTLD_LAZY); |
| | if (handle == NULL) { |
| | fatalf("inittls: failed to dlopen main program"); |
| | return; |
| | } |
| | |
| | |
| | get_ver = dlsym(handle, "android_get_device_api_level"); |
| | dlclose(handle); |
| | if (get_ver != NULL) { |
| | off = (void *)(TLS_SLOT_APP*sizeof(void *)); |
| | |
| | if (*tlsg != off) { |
| | fatalf("tlsg offset wrong, got %ld want %ld\n", *tlsg, off); |
| | } |
| | return; |
| | } |
| |
|
| | err = pthread_key_create(&k, nil); |
| | if(err != 0) { |
| | fatalf("pthread_key_create failed: %d", err); |
| | } |
| | pthread_setspecific(k, (void*)magic1); |
| | |
| | |
| | |
| | |
| | for (i=0; i<384; i++) { |
| | if (*(tlsbase+i) == (void*)magic1) { |
| | *tlsg = (void*)(i*sizeof(void *)); |
| | pthread_setspecific(k, 0); |
| | return; |
| | } |
| | } |
| | fatalf("inittls: could not find pthread key"); |
| | } |
| |
|
| | void (*x_cgo_inittls)(void **tlsg, void **tlsbase) = inittls; |
| |
|