aboutsummaryrefslogtreecommitdiff
path: root/src/runtime
diff options
context:
space:
mode:
Diffstat (limited to 'src/runtime')
-rw-r--r--src/runtime/asm_amd64.s13
-rw-r--r--src/runtime/cgo/gcc_windows_amd64.c6
-rw-r--r--src/runtime/sys_windows_amd64.s41
3 files changed, 51 insertions, 9 deletions
diff --git a/src/runtime/asm_amd64.s b/src/runtime/asm_amd64.s
index d2f7984178..13c8de499e 100644
--- a/src/runtime/asm_amd64.s
+++ b/src/runtime/asm_amd64.s
@@ -201,16 +201,16 @@ nocpuinfo:
JZ needtls
// arg 1: g0, already in DI
MOVQ $setg_gcc<>(SB), SI // arg 2: setg_gcc
+ MOVQ $0, DX // arg 3, 4: not used when using platform's TLS
+ MOVQ $0, CX
#ifdef GOOS_android
MOVQ $runtime·tls_g(SB), DX // arg 3: &tls_g
// arg 4: TLS base, stored in slot 0 (Android's TLS_SLOT_SELF).
// Compensate for tls_g (+16).
MOVQ -16(TLS), CX
-#else
- MOVQ $0, DX // arg 3, 4: not used when using platform's TLS
- MOVQ $0, CX
#endif
#ifdef GOOS_windows
+ MOVQ $runtime·tls_g(SB), DX // arg 3: &tls_g
// Adjust for the Win64 calling convention.
MOVQ CX, R9 // arg 4
MOVQ DX, R8 // arg 3
@@ -251,6 +251,10 @@ needtls:
JMP ok
#endif
+#ifdef GOOS_windows
+ CALL runtime·wintls(SB)
+#endif
+
LEAQ runtime·m0+m_tls(SB), DI
CALL runtime·settls(SB)
@@ -2026,6 +2030,9 @@ TEXT runtime·panicSliceConvert<ABIInternal>(SB),NOSPLIT,$0-16
DATA runtime·tls_g+0(SB)/8, $16
GLOBL runtime·tls_g+0(SB), NOPTR, $8
#endif
+#ifdef GOOS_windows
+GLOBL runtime·tls_g+0(SB), NOPTR, $8
+#endif
// The compiler and assembler's -spectre=ret mode rewrites
// all indirect CALL AX / JMP AX instructions to be
diff --git a/src/runtime/cgo/gcc_windows_amd64.c b/src/runtime/cgo/gcc_windows_amd64.c
index 996947eccf..3ff3c64565 100644
--- a/src/runtime/cgo/gcc_windows_amd64.c
+++ b/src/runtime/cgo/gcc_windows_amd64.c
@@ -13,11 +13,13 @@
static void threadentry(void*);
static void (*setg_gcc)(void*);
+static DWORD *tls_g;
void
x_cgo_init(G *g, void (*setg)(void*), void **tlsg, void **tlsbase)
{
setg_gcc = setg;
+ tls_g = (DWORD *)tlsg;
}
@@ -41,8 +43,8 @@ threadentry(void *v)
* Set specific keys in thread local storage.
*/
asm volatile (
- "movq %0, %%gs:0x28\n" // MOVL tls0, 0x28(GS)
- :: "r"(ts.tls)
+ "movq %0, %%gs:0(%1)\n" // MOVL tls0, 0(tls_g)(GS)
+ :: "r"(ts.tls), "r"(*tls_g)
);
crosscall_amd64(ts.fn, setg_gcc, (void*)ts.g);
diff --git a/src/runtime/sys_windows_amd64.s b/src/runtime/sys_windows_amd64.s
index 4e00f64fae..777726f7c1 100644
--- a/src/runtime/sys_windows_amd64.s
+++ b/src/runtime/sys_windows_amd64.s
@@ -8,6 +8,9 @@
#include "time_windows.h"
#include "cgo/abi_amd64.h"
+// Offsets into Thread Environment Block (pointer in GS)
+#define TEB_TlsSlots 0x1480
+
// void runtime·asmstdcall(void *c);
TEXT runtime·asmstdcall(SB),NOSPLIT|NOFRAME,$0
// asmcgocall will put first argument into CX.
@@ -303,10 +306,10 @@ TEXT runtime·tstart_stdcall(SB),NOSPLIT,$0
MOVQ AX, g_stackguard1(DX)
// Set up tls.
- LEAQ m_tls(CX), SI
- MOVQ SI, 0x28(GS)
+ LEAQ m_tls(CX), DI
MOVQ CX, g_m(DX)
- MOVQ DX, g(SI)
+ MOVQ DX, g(DI)
+ CALL runtime·settls(SB) // clobbers CX
CALL runtime·stackcheck(SB) // clobbers AX,CX
CALL runtime·mstart(SB)
@@ -318,7 +321,8 @@ TEXT runtime·tstart_stdcall(SB),NOSPLIT,$0
// set tls base to DI
TEXT runtime·settls(SB),NOSPLIT,$0
- MOVQ DI, 0x28(GS)
+ MOVQ runtime·tls_g(SB), CX
+ MOVQ DI, 0(CX)(GS)
RET
// Runs on OS stack.
@@ -404,3 +408,32 @@ TEXT runtime·osSetupTLS(SB),NOSPLIT,$0-8
LEAQ m_tls(AX), DI
CALL runtime·settls(SB)
RET
+
+// This is called from rt0_go, which runs on the system stack
+// using the initial stack allocated by the OS.
+TEXT runtime·wintls(SB),NOSPLIT|NOFRAME,$0
+ // Allocate a TLS slot to hold g across calls to external code
+ MOVQ SP, AX
+ ANDQ $~15, SP // alignment as per Windows requirement
+ SUBQ $48, SP // room for SP and 4 args as per Windows requirement
+ // plus one extra word to keep stack 16 bytes aligned
+ MOVQ AX, 32(SP)
+ MOVQ runtime·_TlsAlloc(SB), AX
+ CALL AX
+ MOVQ 32(SP), SP
+
+ MOVQ AX, CX // TLS index
+
+ // Assert that slot is less than 64 so we can use _TEB->TlsSlots
+ CMPQ CX, $64
+ JB ok
+ CALL runtime·abort(SB)
+ok:
+ // Convert the TLS index at CX into
+ // an offset from TEB_TlsSlots.
+ SHLQ $3, CX
+
+ // Save offset from TLS into tls_g.
+ ADDQ $TEB_TlsSlots, CX
+ MOVQ CX, runtime·tls_g(SB)
+ RET