From 6a70f9d07339729639520f4ed8faef8965e6e26e Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Mon, 25 Mar 2013 18:14:02 -0400 Subject: [PATCH] runtime: pass setmg function to cgo_init 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 | 11 +++++++++++ src/pkg/runtime/asm_amd64.s | 8 ++++++++ src/pkg/runtime/cgo/gcc_freebsd_386.c | 14 +++++--------- src/pkg/runtime/cgo/gcc_freebsd_amd64.c | 16 ++++++---------- src/pkg/runtime/cgo/gcc_linux_386.c | 17 +++++------------ src/pkg/runtime/cgo/gcc_linux_amd64.c | 15 ++++++--------- src/pkg/runtime/cgo/gcc_netbsd_386.c | 14 +++++--------- src/pkg/runtime/cgo/gcc_netbsd_amd64.c | 15 ++++++--------- src/pkg/runtime/cgo/gcc_openbsd_386.c | 14 +++++--------- src/pkg/runtime/cgo/gcc_openbsd_amd64.c | 15 ++++++--------- 10 files changed, 63 insertions(+), 76 deletions(-) diff --git a/src/pkg/runtime/asm_386.s b/src/pkg/runtime/asm_386.s index 6bcacf4cc0..805405a737 100644 --- a/src/pkg/runtime/asm_386.s +++ b/src/pkg/runtime/asm_386.s @@ -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) diff --git a/src/pkg/runtime/asm_amd64.s b/src/pkg/runtime/asm_amd64.s index f4cfa576eb..af2064ff3a 100644 --- a/src/pkg/runtime/asm_amd64.s +++ b/src/pkg/runtime/asm_amd64.s @@ -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) diff --git a/src/pkg/runtime/cgo/gcc_freebsd_386.c b/src/pkg/runtime/cgo/gcc_freebsd_386.c index 7c62a1bc49..6797824c6d 100644 --- a/src/pkg/runtime/cgo/gcc_freebsd_386.c +++ b/src/pkg/runtime/cgo/gcc_freebsd_386.c @@ -10,13 +10,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,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; diff --git a/src/pkg/runtime/cgo/gcc_freebsd_amd64.c b/src/pkg/runtime/cgo/gcc_freebsd_amd64.c index 6be8bd251a..eb342a2ff5 100644 --- a/src/pkg/runtime/cgo/gcc_freebsd_amd64.c +++ b/src/pkg/runtime/cgo/gcc_freebsd_amd64.c @@ -10,20 +10,21 @@ #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; } diff --git a/src/pkg/runtime/cgo/gcc_linux_386.c b/src/pkg/runtime/cgo/gcc_linux_386.c index 9357a63f71..c25c7b70fc 100644 --- a/src/pkg/runtime/cgo/gcc_linux_386.c +++ b/src/pkg/runtime/cgo/gcc_linux_386.c @@ -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; diff --git a/src/pkg/runtime/cgo/gcc_linux_amd64.c b/src/pkg/runtime/cgo/gcc_linux_amd64.c index bc76117d35..bd7c88d991 100644 --- a/src/pkg/runtime/cgo/gcc_linux_amd64.c +++ b/src/pkg/runtime/cgo/gcc_linux_amd64.c @@ -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; } diff --git a/src/pkg/runtime/cgo/gcc_netbsd_386.c b/src/pkg/runtime/cgo/gcc_netbsd_386.c index 09b271df4f..b399e16dc4 100644 --- a/src/pkg/runtime/cgo/gcc_netbsd_386.c +++ b/src/pkg/runtime/cgo/gcc_netbsd_386.c @@ -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; diff --git a/src/pkg/runtime/cgo/gcc_netbsd_amd64.c b/src/pkg/runtime/cgo/gcc_netbsd_amd64.c index 080c59ba49..f27e142ce1 100644 --- a/src/pkg/runtime/cgo/gcc_netbsd_amd64.c +++ b/src/pkg/runtime/cgo/gcc_netbsd_amd64.c @@ -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; } diff --git a/src/pkg/runtime/cgo/gcc_openbsd_386.c b/src/pkg/runtime/cgo/gcc_openbsd_386.c index 80be31b9c3..6422d1b931 100644 --- a/src/pkg/runtime/cgo/gcc_openbsd_386.c +++ b/src/pkg/runtime/cgo/gcc_openbsd_386.c @@ -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; diff --git a/src/pkg/runtime/cgo/gcc_openbsd_amd64.c b/src/pkg/runtime/cgo/gcc_openbsd_amd64.c index e9cc8184bd..5a5a171143 100644 --- a/src/pkg/runtime/cgo/gcc_openbsd_amd64.c +++ b/src/pkg/runtime/cgo/gcc_openbsd_amd64.c @@ -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; } -- 2.48.1