]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: pass setmg function to cgo_init
authorRuss Cox <rsc@golang.org>
Mon, 25 Mar 2013 22:14:02 +0000 (18:14 -0400)
committerRuss Cox <rsc@golang.org>
Mon, 25 Mar 2013 22:14:02 +0000 (18:14 -0400)
This keeps the logic about how to set the thread-local variables
m and g in code compiled and linked by the gc toolchain,
an important property for upcoming cgo changes.

It's also just a nice cleanup: one less place to update when
these details change.

R=golang-dev, r
CC=golang-dev
https://golang.org/cl/7560048

src/pkg/runtime/asm_386.s
src/pkg/runtime/asm_amd64.s
src/pkg/runtime/cgo/gcc_freebsd_386.c
src/pkg/runtime/cgo/gcc_freebsd_amd64.c
src/pkg/runtime/cgo/gcc_linux_386.c
src/pkg/runtime/cgo/gcc_linux_amd64.c
src/pkg/runtime/cgo/gcc_netbsd_386.c
src/pkg/runtime/cgo/gcc_netbsd_amd64.c
src/pkg/runtime/cgo/gcc_openbsd_386.c
src/pkg/runtime/cgo/gcc_openbsd_amd64.c

index 6bcacf4cc04d6d995384e8751af4319752f06d32..805405a73777189f1bd961d47d466c68e7a3b6bd 100644 (file)
@@ -37,6 +37,8 @@ nocpuinfo:
        MOVL    _cgo_init(SB), AX
        TESTL   AX, AX
        JZ      needtls
+       MOVL    $setmg_gcc<>(SB), BX
+       MOVL    BX, 4(SP)
        MOVL    BP, 0(SP)
        CALL    AX
        // skip runtime·ldt0setup(SB) and tls test after _cgo_init for non-windows
@@ -643,6 +645,15 @@ settls:
        MOVL    BX, g(CX)
        RET
 
+// void setmg_gcc(M*, G*); set m and g. for use by gcc
+TEXT setmg_gcc<>(SB), 7, $0    
+       get_tls(AX)
+       MOVL    mm+0(FP), DX
+       MOVL    DX, m(AX)
+       MOVL    gg+4(FP), DX
+       MOVL    DX,g (AX)
+       RET
+
 // check that SP is in range [g->stackbase, g->stackguard)
 TEXT runtime·stackcheck(SB), 7, $0
        get_tls(CX)
index f4cfa576eb71d82abc56e031b882556f4af7aa7b..af2064ff3aeb46813490681b8971df479cd23a1f 100644 (file)
@@ -37,6 +37,7 @@ nocpuinfo:
        JZ      needtls
        // g0 already in DI
        MOVQ    DI, CX  // Win64 uses CX for first parameter
+       MOVQ    $setmg_gcc<>(SB), SI
        CALL    AX
        CMPL    runtime·iswindows(SB), $0
        JEQ ok
@@ -682,6 +683,13 @@ settls:
        MOVQ    BX, g(CX)
        RET
 
+// void setmg_gcc(M*, G*); set m and g called from gcc.
+TEXT setmg_gcc<>(SB),7,$0
+       get_tls(AX)
+       MOVQ    DI, m(AX)
+       MOVQ    SI, g(AX)
+       RET
+
 // check that SP is in range [g->stackbase, g->stackguard)
 TEXT runtime·stackcheck(SB), 7, $0
        get_tls(CX)
index 7c62a1bc49bf136c0bd9bb3e2ae06b2b3664e27e..6797824c6d1d1728f97f615d9a5df0dd72767d0e 100644 (file)
 #include "libcgo.h"
 
 static void* threadentry(void*);
+static void (*setmg_gcc)(void*, void*);
 
 void
-x_cgo_init(G *g)
+x_cgo_init(G *g, void (*setmg)(void*, void*))
 {
        pthread_attr_t attr;
        size_t size;
 
+       setmg_gcc = setmg;
        pthread_attr_init(&attr);
        pthread_attr_getstacksize(&attr, &size);
        g->stackguard = (uintptr)&attr - size + 4096;
@@ -66,15 +68,9 @@ threadentry(void *v)
        ts.g->stackguard = (uintptr)&ts - ts.g->stackguard + 4096;
 
        /*
-        * Set specific keys.  On FreeBSD/ELF, the thread local storage
-        * is just before %gs:0.  Our dynamic 8.out's reserve 8 bytes
-        * for the two words g and m at %gs:-8 and %gs:-4.
+        * Set specific keys.
         */
-       asm volatile (
-               "movl %0, %%gs:-8\n"    // MOVL g, -8(GS)
-               "movl %1, %%gs:-4\n"    // MOVL m, -4(GS)
-               :: "r"(ts.g), "r"(ts.m)
-       );
+       setmg_gcc((void*)ts.m, (void*)ts.g);
 
        crosscall_386(ts.fn);
        return nil;
index 6be8bd251ab202ad76b6c88ccf67b9efc24f1e8d..eb342a2ff5543cc0e996c55322ebfa865ce32713 100644 (file)
 #include "libcgo.h"
 
 static void* threadentry(void*);
+static void (*setmg_gcc)(void*, void*);
 
 void
-x_cgo_init(G *g)
+x_cgo_init(G *g, void (*setmg)(void*, void*))
 {
        pthread_attr_t attr;
        size_t size;
 
+       setmg_gcc = setmg;
        pthread_attr_init(&attr);
        pthread_attr_getstacksize(&attr, &size);
        g->stackguard = (uintptr)&attr - size + 4096;
        pthread_attr_destroy(&attr);
 }
 
-
 void
 _cgo_sys_thread_start(ThreadStart *ts)
 {
@@ -67,15 +68,10 @@ threadentry(void *v)
        ts.g->stackguard = (uintptr)&ts - ts.g->stackguard + 4096;
 
        /*
-        * Set specific keys.  On FreeBSD/ELF, the thread local storage
-        * is just before %fs:0.  Our dynamic 6.out's reserve 16 bytes
-        * for the two words g and m at %fs:-16 and %fs:-8.
+        * Set specific keys.
         */
-       asm volatile (
-               "movq %0, %%fs:-16\n"   // MOVL g, -16(FS)
-               "movq %1, %%fs:-8\n"    // MOVL m, -8(FS)
-               :: "r"(ts.g), "r"(ts.m)
-       );
+       setmg_gcc((void*)ts.m, (void*)ts.g);
+
        crosscall_amd64(ts.fn);
        return nil;
 }
index 9357a63f718b8481f29868e9bac7435f1b4f8135..c25c7b70fcfdc40cebb3436fb5d51bf2dd9a688b 100644 (file)
@@ -8,13 +8,15 @@
 #include "libcgo.h"
 
 static void *threadentry(void*);
+static void (*setmg_gcc)(void*, void*);
 
 void
-x_cgo_init(G *g)
+x_cgo_init(G *g, void (*setmg)(void*, void*))
 {
        pthread_attr_t attr;
        size_t size;
 
+       setmg_gcc = setmg;
        pthread_attr_init(&attr);
        pthread_attr_getstacksize(&attr, &size);
        g->stackguard = (uintptr)&attr - size + 4096;
@@ -69,18 +71,9 @@ threadentry(void *v)
        ts.g->stackguard = (uintptr)&ts - ts.g->stackguard + 4096;
 
        /*
-        * Set specific keys.  On Linux/ELF, the thread local storage
-        * is just before %gs:0.  Our dynamic 8.out's reserve 8 bytes
-        * for the two words g and m at %gs:-8 and %gs:-4.
-        * Xen requires us to access those words indirect from %gs:0
-        * which points at itself.
+        * Set specific keys.
         */
-       asm volatile (
-               "movl %%gs:0, %%eax\n"          // MOVL 0(GS), tmp
-               "movl %0, -8(%%eax)\n"  // MOVL g, -8(GS)
-               "movl %1, -4(%%eax)\n"  // MOVL m, -4(GS)
-               :: "r"(ts.g), "r"(ts.m) : "%eax"
-       );
+       setmg_gcc((void*)ts.m, (void*)ts.g);
 
        crosscall_386(ts.fn);
        return nil;
index bc76117d355de5070f50bfa8e475e6d3a73b8881..bd7c88d9917da09897ea35b7192f3d0c4bc66942 100644 (file)
@@ -8,13 +8,15 @@
 #include "libcgo.h"
 
 static void* threadentry(void*);
+static void (*setmg_gcc)(void*, void*);
 
 void
-x_cgo_init(G* g)
+x_cgo_init(G* g, void (*setmg)(void*, void*))
 {
        pthread_attr_t attr;
        size_t size;
 
+       setmg_gcc = setmg;
        pthread_attr_init(&attr);
        pthread_attr_getstacksize(&attr, &size);
        g->stackguard = (uintptr)&attr - size + 4096;
@@ -64,15 +66,10 @@ threadentry(void *v)
        ts.g->stackguard = (uintptr)&ts - ts.g->stackguard + 4096;
 
        /*
-        * Set specific keys.  On Linux/ELF, the thread local storage
-        * is just before %fs:0.  Our dynamic 6.out's reserve 16 bytes
-        * for the two words g and m at %fs:-16 and %fs:-8.
+        * Set specific keys.
         */
-       asm volatile (
-               "movq %0, %%fs:-16\n"   // MOVL g, -16(FS)
-               "movq %1, %%fs:-8\n"    // MOVL m, -8(FS)
-               :: "r"(ts.g), "r"(ts.m)
-       );
+       setmg_gcc((void*)ts.m, (void*)ts.g);
+
        crosscall_amd64(ts.fn);
        return nil;
 }
index 09b271df4fdefef6f2d1d2350bc1423eaf1f0840..b399e16dc45917842dfa9b48d8b959d962b01805 100644 (file)
@@ -9,13 +9,15 @@
 #include "libcgo.h"
 
 static void* threadentry(void*);
+static void (*setmg_gcc)(void*, void*);
 
 void
-x_cgo_init(G *g)
+x_cgo_init(G *g, void (*setmg)(void*, void*))
 {
        pthread_attr_t attr;
        size_t size;
 
+       setmg_gcc = setmg;
        pthread_attr_init(&attr);
        pthread_attr_getstacksize(&attr, &size);
        g->stackguard = (uintptr)&attr - size + 4096;
@@ -65,15 +67,9 @@ threadentry(void *v)
        ts.g->stackguard = (uintptr)&ts - ts.g->stackguard + 4096;
 
        /*
-        * Set specific keys.  On NetBSD/ELF, the thread local storage
-        * is just before %gs:0.  Our dynamic 8.out's reserve 8 bytes
-        * for the two words g and m at %gs:-8 and %gs:-4.
+        * Set specific keys.
         */
-       asm volatile (
-               "movl %0, %%gs:-8\n"    // MOVL g, -8(GS)
-               "movl %1, %%gs:-4\n"    // MOVL m, -4(GS)
-               :: "r"(ts.g), "r"(ts.m)
-       );
+       setmg_gcc((void*)ts.m, (void*)ts.g);
 
        crosscall_386(ts.fn);
        return nil;
index 080c59ba499a82e95dc47c53574f8552d2774237..f27e142ce1617d54367e2e8c4b135f69106a4750 100644 (file)
@@ -9,13 +9,15 @@
 #include "libcgo.h"
 
 static void* threadentry(void*);
+static void (*setmg_gcc)(void*, void*);
 
 void
-x_cgo_init(G *g)
+x_cgo_init(G *g, void (*setmg)(void*, void*))
 {
        pthread_attr_t attr;
        size_t size;
 
+       setmg_gcc = setmg;
        pthread_attr_init(&attr);
        pthread_attr_getstacksize(&attr, &size);
        g->stackguard = (uintptr)&attr - size + 4096;
@@ -66,15 +68,10 @@ threadentry(void *v)
        ts.g->stackguard = (uintptr)&ts - ts.g->stackguard + 4096;
 
        /*
-        * Set specific keys.  On NetBSD/ELF, the thread local storage
-        * is just before %fs:0.  Our dynamic 6.out's reserve 16 bytes
-        * for the two words g and m at %fs:-16 and %fs:-8.
+        * Set specific keys.
         */
-       asm volatile (
-               "movq %0, %%fs:-16\n"   // MOVL g, -16(FS)
-               "movq %1, %%fs:-8\n"    // MOVL m, -8(FS)
-               :: "r"(ts.g), "r"(ts.m)
-       );
+       setmg_gcc((void*)ts.m, (void*)ts.g);
+
        crosscall_amd64(ts.fn);
        return nil;
 }
index 80be31b9c3ad24ac049fa4131667c25e74e90a0d..6422d1b931f6b78fedab50444ee25a066eafda7a 100644 (file)
@@ -11,6 +11,7 @@
 #include "libcgo.h"
 
 static void* threadentry(void*);
+static void (*setmg_gcc)(void*, void*);
 
 // TCB_SIZE is sizeof(struct thread_control_block),
 // as defined in /usr/src/lib/librthread/tcb.h
@@ -82,12 +83,13 @@ pthread_create(pthread_t *thread, const pthread_attr_t *attr,
 }
 
 void
-x_cgo_init(G *g)
+x_cgo_init(G *g, void (*setmg)(void*, void*))
 {
        pthread_attr_t attr;
        size_t size;
        void *handle;
 
+       setmg_gcc = setmg;
        pthread_attr_init(&attr);
        pthread_attr_getstacksize(&attr, &size);
        g->stackguard = (uintptr)&attr - size + 4096;
@@ -154,15 +156,9 @@ threadentry(void *v)
        ts.g->stackguard = (uintptr)&ts - ts.g->stackguard + 4096;
 
        /*
-        * Set specific keys.  On OpenBSD/ELF, the thread local storage
-        * is just before %gs:0.  Our dynamic 8.out's reserve 8 bytes
-        * for the two words g and m at %gs:-8 and %gs:-4.
+        * Set specific keys.
         */
-       asm volatile (
-               "movl %0, %%gs:-8\n"    // MOVL g, -8(GS)
-               "movl %1, %%gs:-4\n"    // MOVL m, -4(GS)
-               :: "r"(ts.g), "r"(ts.m)
-       );
+       setmg_gcc((void*)ts.m, (void*)ts.g);
 
        crosscall_386(ts.fn);
        return nil;
index e9cc8184bdbb1f9775529bcc90d5c2ae3366cc57..5a5a171143bb7bbfbb30b01c37ef46b6cb133bad 100644 (file)
@@ -11,6 +11,7 @@
 #include "libcgo.h"
 
 static void* threadentry(void*);
+static void (*setmg_gcc)(void*, void*);
 
 // TCB_SIZE is sizeof(struct thread_control_block),
 // as defined in /usr/src/lib/librthread/tcb.h
@@ -82,12 +83,13 @@ pthread_create(pthread_t *thread, const pthread_attr_t *attr,
 }
 
 void
-x_cgo_init(G *g)
+x_cgo_init(G *g, void (*setmg)(void*, void*))
 {
        pthread_attr_t attr;
        size_t size;
        void *handle;
 
+       setmg_gcc = setmg;
        pthread_attr_init(&attr);
        pthread_attr_getstacksize(&attr, &size);
        g->stackguard = (uintptr)&attr - size + 4096;
@@ -155,15 +157,10 @@ threadentry(void *v)
        ts.g->stackguard = (uintptr)&ts - ts.g->stackguard + 4096;
 
        /*
-        * Set specific keys.  On OpenBSD/ELF, the thread local storage
-        * is just before %fs:0.  Our dynamic 6.out's reserve 16 bytes
-        * for the two words g and m at %fs:-16 and %fs:-8.
+        * Set specific keys.
         */
-       asm volatile (
-               "movq %0, %%fs:-16\n"   // MOVL g, -16(FS)
-               "movq %1, %%fs:-8\n"    // MOVL m, -8(FS)
-               :: "r"(ts.g), "r"(ts.m)
-       );
+       setmg_gcc((void*)ts.m, (void*)ts.g);
+
        crosscall_amd64(ts.fn);
        return nil;
 }