diff options
| author | qmuntal <quimmuntal@gmail.com> | 2022-09-19 12:19:38 +0200 |
|---|---|---|
| committer | Alex Brainman <alex.brainman@gmail.com> | 2022-11-14 20:43:12 +0000 |
| commit | da564d0006e2cc286fecb3cec94ed143a2667866 (patch) | |
| tree | 1601b9e73eec4bd72c041e368be4a8f1d5143e55 /src/runtime/asm_amd64.s | |
| parent | 0f0aa5d8a6a0253627d58b3aa083b24a1091933f (diff) | |
| download | go-da564d0006e2cc286fecb3cec94ed143a2667866.tar.xz | |
runtime,cmd/internal/obj/x86: use TEB TLS slots on windows/amd64
This CL redesign how we get the TLS pointer on windows/amd64.
We were previously reading it from the [TEB] arbitrary data slot,
located at 0x28(GS), which can only hold 1 TLS pointer.
With this CL, we will read the TLS pointer from the TEB TLS slot array,
located at 0x1480(GS). The TLS slot array can hold multiple
TLS pointers, up to 64, so multiple Go runtimes running on the
same thread can coexists with different TLS.
Each new TLS slot has to be allocated via [TlsAlloc],
which returns the slot index. This index can then be used to get the
slot offset from GS with the following formula: 0x1480 + index*8
The slot index is fixed per Go runtime, so we can store it
in runtime.tls_g and use it latter on to read/update the TLS pointer.
Loading the TLS pointer requires the following asm instructions:
MOVQ runtime.tls_g, AX
MOVQ AX(GS), AX
Notice that this approach is also implemented on windows/arm64.
[TEB]: https://en.wikipedia.org/wiki/Win32_Thread_Information_Block
[TlsAlloc]: https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-tlsalloc
Updates #22192
Change-Id: Idea7119fd76a3cd083979a4d57ed64b552fa101b
Reviewed-on: https://go-review.googlesource.com/c/go/+/431775
Reviewed-by: Cherry Mui <cherryyz@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Quim Muntal <quimmuntal@gmail.com>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
Diffstat (limited to 'src/runtime/asm_amd64.s')
| -rw-r--r-- | src/runtime/asm_amd64.s | 13 |
1 files changed, 10 insertions, 3 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 |
