]> Cypherpunks repositories - gostls13.git/commitdiff
cmd,runtime: TLS setup for android/386
authorHyang-Ah Hana Kim <hyangah@gmail.com>
Thu, 5 Nov 2015 21:32:27 +0000 (16:32 -0500)
committerHyang-Ah Hana Kim <hyangah@gmail.com>
Wed, 11 Nov 2015 21:59:24 +0000 (21:59 +0000)
Same ugly hack as https://go-review.googlesource.com/15991.

Update golang/go#9327.

Change-Id: I58284e83268a15de95eabc833c3e01bf1e3faa2e
Reviewed-on: https://go-review.googlesource.com/16678
Reviewed-by: David Crawshaw <crawshaw@golang.org>
src/cmd/internal/obj/x86/asm6.go
src/cmd/link/internal/ld/sym.go
src/runtime/cgo/gcc_android_386.c [new file with mode: 0644]
src/runtime/cgo/gcc_linux_386.c
src/runtime/rt0_android_386.s [new file with mode: 0644]
src/runtime/sys_linux_386.s

index 919e00b6e4bd708d54ad46169fa7afb286b222ed..13ab240c6420df44d1b5933c2adfa45431b9113a 100644 (file)
@@ -1975,6 +1975,9 @@ func prefixof(ctxt *obj.Link, p *obj.Prog, a *obj.Addr) int {
                        if p.Mode == 32 {
                                switch ctxt.Headtype {
                                default:
+                                       if isAndroid {
+                                               return 0x65 // GS
+                                       }
                                        log.Fatalf("unknown TLS base register for %s", obj.Headstr(ctxt.Headtype))
 
                                case obj.Hdarwin,
index da5776d351c7b1388b67ffbc2e81a572f6669085..731f3ede94efc5c72c698fd10531fe6453fb5b8c 100644 (file)
@@ -102,10 +102,18 @@ func linknew(arch *LinkArch) *Link {
                obj.Hopenbsd,
                obj.Hdragonfly,
                obj.Hsolaris:
-               if obj.Getgoos() == "android" && ctxt.Arch.Thechar == '6' {
-                       // Android/x86 constant - offset from 0(FS) to our
-                       // TLS slot. Explained in src/runtime/cgo/gcc_android_*.c
-                       ctxt.Tlsoffset = 0x1d0
+               if obj.Getgoos() == "android" {
+                       switch ctxt.Arch.Thechar {
+                       case '6':
+                               // Android/amd64 constant - offset from 0(FS) to our TLS slot.
+                               // Explained in src/runtime/cgo/gcc_android_*.c
+                               ctxt.Tlsoffset = 0x1d0
+                       case '8':
+                               // Android/386 constant - offset from 0(GS) to our TLS slot.
+                               ctxt.Tlsoffset = 0xf8
+                       default:
+                               ctxt.Tlsoffset = -1 * ctxt.Arch.Ptrsize
+                       }
                } else {
                        ctxt.Tlsoffset = -1 * ctxt.Arch.Ptrsize
                }
diff --git a/src/runtime/cgo/gcc_android_386.c b/src/runtime/cgo/gcc_android_386.c
new file mode 100644 (file)
index 0000000..a82d7d0
--- /dev/null
@@ -0,0 +1,87 @@
+// Copyright 2015 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include <string.h> /* for strerror */
+#include <pthread.h>
+#include <signal.h>
+#include "libcgo.h"
+
+static void* threadentry(void*);
+static pthread_key_t k1;
+
+#define magic1 (0x23581321U)
+
+static void
+inittls(void)
+{
+       uint32 x;
+       pthread_key_t tofree[128], k;
+       int i, ntofree;
+
+       /*
+        * Same logic, code as gcc_android_amd64.c:/inittls.
+        * Note that this is a temporary hack that should be fixed soon.
+        *
+        * TODO: fix this.
+        *
+        * The linker and runtime hard-code this constant offset
+        * from %gs where we expect to find g. Disgusting.
+        *
+        * Known to src/cmd/link/internal/ld/sym.go:/0xf8
+        * and to src/runtime/sys_linux_386.s:/0xf8 or /GOOS_android.
+        * TODO(hyangah): check 0xb0 works with API23+
+        *
+        * As disgusting as on the darwin/386, darwin/amd64.
+        */
+       ntofree = 0;
+       for(;;) {
+               if(pthread_key_create(&k, nil) < 0) {
+                       fprintf(stderr, "runtime/cgo: pthread_key_create failed\n");
+                       abort();
+               }
+               pthread_setspecific(k, (void*)magic1);
+               asm volatile("movl %%gs:0xf8, %0" : "=r"(x));
+               pthread_setspecific(k, 0);
+               if (x == magic1) {
+                       k1 = k;
+                       break;
+               }
+               if(ntofree >= nelem(tofree)) {
+                       fprintf(stderr, "runtime/cgo: could not obtain pthread_keys\n");
+                       fprintf(stderr, "\ttried");
+                       for(i=0; i<ntofree; i++)
+                               fprintf(stderr, " %#x", (unsigned)tofree[i]);
+                       fprintf(stderr, "\n");
+                       abort();
+               }
+               tofree[ntofree++] = k;
+       }
+       // TODO: output to stderr is not useful for apps.
+       // Can we fall back to Android's log library?
+
+       /*
+        * We got the key we wanted.  Free the others.
+        */
+       for(i=0; i<ntofree; i++) {
+               pthread_key_delete(tofree[i]);
+       }
+}
+
+
+static void*
+threadentry(void *v)
+{
+       ThreadStart ts;
+
+       ts = *(ThreadStart*)v;
+       free(v);
+
+       pthread_setspecific(k1, (void*)ts.g);
+
+       crosscall_386(ts.fn);
+       return nil;
+}
+
+void (*x_cgo_inittls)(void) = inittls;
+void* (*x_cgo_threadentry)(void*) = threadentry;
index 9801c87bdbc22f8b0d2460c914bdeba2fa01cb25..8fb7130e31b01d37c5e7896775def5edd315ac28 100644 (file)
 static void *threadentry(void*);
 static void (*setg_gcc)(void*);
 
+// These will be set in gcc_android_386.c for android-specific customization.
+void (*x_cgo_inittls)(void);
+void* (*x_cgo_threadentry)(void*);
+
 void
 x_cgo_init(G *g, void (*setg)(void*))
 {
@@ -21,6 +25,10 @@ x_cgo_init(G *g, void (*setg)(void*))
        pthread_attr_getstacksize(&attr, &size);
        g->stacklo = (uintptr)&attr - size + 4096;
        pthread_attr_destroy(&attr);
+
+       if (x_cgo_inittls) {
+               x_cgo_inittls();
+       }
 }
 
 
@@ -57,6 +65,10 @@ _cgo_sys_thread_start(ThreadStart *ts)
 static void*
 threadentry(void *v)
 {
+       if (x_cgo_threadentry) {
+               return x_cgo_threadentry(v);
+       }
+
        ThreadStart ts;
 
        ts = *(ThreadStart*)v;
diff --git a/src/runtime/rt0_android_386.s b/src/runtime/rt0_android_386.s
new file mode 100644 (file)
index 0000000..9d20fc8
--- /dev/null
@@ -0,0 +1,32 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+TEXT _rt0_386_android(SB),NOSPLIT,$8
+       MOVL    8(SP), AX  // argc
+       LEAL    12(SP), BX  // argv
+       MOVL    AX, 0(SP)
+       MOVL    BX, 4(SP)
+       CALL    main(SB)
+       INT     $3
+
+TEXT _rt0_386_android_lib(SB),NOSPLIT,$0
+       PUSHL   $_rt0_386_android_argv(SB)  // argv
+       PUSHL   $1  // argc
+       CALL    _rt0_386_linux_lib(SB)
+       POPL    AX
+       POPL    AX
+       RET
+
+DATA _rt0_386_android_argv+0x00(SB)/4,$_rt0_386_android_argv0(SB)
+DATA _rt0_386_android_argv+0x04(SB)/4,$0  // argv terminate
+DATA _rt0_386_android_argv+0x08(SB)/4,$0  // envp terminate
+DATA _rt0_386_android_argv+0x0c(SB)/4,$0  // auxv terminate
+GLOBL _rt0_386_android_argv(SB),NOPTR,$0x10
+
+// TODO: wire up necessary VDSO (see os_linux_386.go)
+
+DATA _rt0_386_android_argv0(SB)/8, $"gojni"
+GLOBL _rt0_386_android_argv0(SB),RODATA,$8
index 9e0e87cafc2370149fc0536910f741024330b03d..a52c4b2588554eb248e9fb6d2375d6f638ec8064 100644 (file)
@@ -405,6 +405,15 @@ TEXT runtime·setldt(SB),NOSPLIT,$32
        MOVL    entry+0(FP), BX // entry
        MOVL    address+4(FP), CX       // base address
 
+#ifdef GOOS_android
+       /*
+        * Same as in sys_darwin_386.s:/ugliness, different constant.
+        * address currently holds m->tls, which must be %gs:0xf8.
+        * See cgo/gcc_android_386.c for the derivation of the constant.
+        */
+       SUBL    $0xf8, CX
+       MOVL    CX, 0(CX)
+#else
        /*
         * When linking against the system libraries,
         * we use its pthread_create and let it set up %gs
@@ -420,6 +429,7 @@ TEXT runtime·setldt(SB),NOSPLIT,$32
         */
        ADDL    $0x4, CX        // address
        MOVL    CX, 0(CX)
+#endif
 
        // set up user_desc
        LEAL    16(SP), AX      // struct user_desc