diff options
Diffstat (limited to 'src/runtime')
| -rw-r--r-- | src/runtime/asm_amd64.s | 13 | ||||
| -rw-r--r-- | src/runtime/cgo/gcc_windows_amd64.c | 6 | ||||
| -rw-r--r-- | src/runtime/sys_windows_amd64.s | 41 |
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 |
