diff options
Diffstat (limited to 'src/runtime')
| -rw-r--r-- | src/runtime/asm_386.s | 19 | ||||
| -rw-r--r-- | src/runtime/cgo/gcc_windows_386.c | 12 | ||||
| -rw-r--r-- | src/runtime/sys_windows_386.s | 46 |
3 files changed, 60 insertions, 17 deletions
diff --git a/src/runtime/asm_386.s b/src/runtime/asm_386.s index e16880c950..02179d2ee9 100644 --- a/src/runtime/asm_386.s +++ b/src/runtime/asm_386.s @@ -171,8 +171,12 @@ nocpuinfo: MOVL $runtime·tls_g(SB), 8(SP) // arg 3: &tls_g #else MOVL $0, BX - MOVL BX, 12(SP) // arg 3,4: not used when using platform's TLS - MOVL BX, 8(SP) + MOVL BX, 12(SP) // arg 4: not used when using platform's TLS +#ifdef GOOS_windows + MOVL $runtime·tls_g(SB), 8(SP) // arg 3: &tls_g +#else + MOVL BX, 8(SP) // arg 3: not used when using platform's TLS +#endif #endif MOVL $setg_gcc<>(SB), BX MOVL BX, 4(SP) // arg 2: setg_gcc @@ -795,14 +799,15 @@ havem: TEXT runtime·setg(SB), NOSPLIT, $0-4 MOVL gg+0(FP), BX #ifdef GOOS_windows + MOVL runtime·tls_g(SB), CX CMPL BX, $0 JNE settls - MOVL $0, 0x14(FS) + MOVL $0, 0(CX)(FS) RET settls: MOVL g_m(BX), AX LEAL m_tls(AX), AX - MOVL AX, 0x14(FS) + MOVL AX, 0(CX)(FS) #endif get_tls(CX) MOVL BX, g(CX) @@ -867,6 +872,9 @@ rdtsc: JMP done TEXT ldt0setup<>(SB),NOSPLIT,$16-0 +#ifdef GOOS_windows + CALL runtime·wintls(SB) +#endif // set up ldt 7 to point at m0.tls // ldt 1 would be fine on Linux, but on OS X, 7 is as low as we can go. // the entry number is just a hint. setldt will set up GS with what it used. @@ -1577,3 +1585,6 @@ TEXT runtime·panicExtendSlice3CU(SB),NOSPLIT,$0-12 DATA runtime·tls_g+0(SB)/4, $8 GLOBL runtime·tls_g+0(SB), NOPTR, $4 #endif +#ifdef GOOS_windows +GLOBL runtime·tls_g+0(SB), NOPTR, $4 +#endif diff --git a/src/runtime/cgo/gcc_windows_386.c b/src/runtime/cgo/gcc_windows_386.c index 56fbaac9b8..0f4f01c7c0 100644 --- a/src/runtime/cgo/gcc_windows_386.c +++ b/src/runtime/cgo/gcc_windows_386.c @@ -12,10 +12,12 @@ #include "libcgo_windows.h" static void threadentry(void*); +static DWORD *tls_g; void -x_cgo_init(G *g) +x_cgo_init(G *g, void (*setg)(void*), void **tlsg, void **tlsbase) { + tls_g = (DWORD *)tlsg; } @@ -39,10 +41,10 @@ threadentry(void *v) * Set specific keys in thread local storage. */ asm volatile ( - "movl %0, %%fs:0x14\n" // MOVL tls0, 0x14(FS) - "movl %%fs:0x14, %%eax\n" // MOVL 0x14(FS), tmp - "movl %1, 0(%%eax)\n" // MOVL g, 0(FS) - :: "r"(ts.tls), "r"(ts.g) : "%eax" + "movl %0, %%fs:0(%1)\n" // MOVL tls0, 0(tls_g)(FS) + "movl %%fs:0(%1), %%eax\n" // MOVL 0(tls_g)(FS), tmp + "movl %2, 0(%%eax)\n" // MOVL g, 0(AX) + :: "r"(ts.tls), "r"(*tls_g), "r"(ts.g) : "%eax" ); crosscall_386(ts.fn); diff --git a/src/runtime/sys_windows_386.s b/src/runtime/sys_windows_386.s index cf3a439523..8713f7d0d9 100644 --- a/src/runtime/sys_windows_386.s +++ b/src/runtime/sys_windows_386.s @@ -7,6 +7,9 @@ #include "textflag.h" #include "time_windows.h" +// Offsets into Thread Environment Block (pointer in FS) +#define TEB_TlsSlots 0xE10 + // void runtime·asmstdcall(void *c); TEXT runtime·asmstdcall(SB),NOSPLIT,$0 MOVL fn+0(FP), BX @@ -222,7 +225,7 @@ TEXT runtime·callbackasm1(SB),NOSPLIT,$0 RET // void tstart(M *newm); -TEXT tstart<>(SB),NOSPLIT,$0 +TEXT tstart<>(SB),NOSPLIT,$8-4 MOVL newm+0(FP), CX // m MOVL m_g0(CX), DX // g @@ -236,10 +239,11 @@ TEXT tstart<>(SB),NOSPLIT,$0 MOVL AX, g_stackguard1(DX) // Set up tls. - LEAL m_tls(CX), SI - MOVL SI, 0x14(FS) + LEAL m_tls(CX), DI MOVL CX, g_m(DX) - MOVL DX, g(SI) + MOVL DX, g(DI) + MOVL DI, 4(SP) + CALL runtime·setldt(SB) // clobbers CX and DX // Someday the convention will be D is always cleared. CLD @@ -266,10 +270,11 @@ TEXT runtime·tstart_stdcall(SB),NOSPLIT,$0 RET -// setldt(int entry, int address, int limit) -TEXT runtime·setldt(SB),NOSPLIT,$0 - MOVL base+4(FP), CX - MOVL CX, 0x14(FS) +// setldt(int slot, int base, int size) +TEXT runtime·setldt(SB),NOSPLIT,$0-12 + MOVL base+4(FP), DX + MOVL runtime·tls_g(SB), CX + MOVL DX, 0(CX)(FS) RET // Runs on OS stack. @@ -356,3 +361,28 @@ loop: useQPC: JMP runtime·nanotimeQPC(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 + MOVL SP, BP + MOVL runtime·_TlsAlloc(SB), AX + CALL AX + MOVL BP, SP + + MOVL AX, CX // TLS index + + // Assert that slot is less than 64 so we can use _TEB->TlsSlots + CMPL CX, $64 + JB ok + CALL runtime·abort(SB) +ok: + // Convert the TLS index at CX into + // an offset from TEB_TlsSlots. + SHLL $2, CX + + // Save offset from TLS into tls_g. + ADDL $TEB_TlsSlots, CX + MOVL CX, runtime·tls_g(SB) + RET |
