mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
runtime,cmd/internal/obj/x86: use TEB TLS slots on windows/i386
This CL redesign how we get the TLS pointer on windows/i386. It applies the same changes as done in CL 431775 for windows/amd64. We were previously reading it from the [TEB] arbitrary data slot, located at 0x14(FS), which can only hold 1 TLS pointer. With this CL, we will read the TLS pointer from the TEB TLS slot array, located at 0xE10(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: 0xE10 + index*4. 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(FS), AX Notice that this approach will now be implemented in all the supported windows arches. [TEB]: https://en.wikipedia.org/wiki/Win32_Thread_Information_Block [TlsAlloc]: https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-tlsalloc Change-Id: If4550b0d44694ee6480d4093b851f4991a088b32 Reviewed-on: https://go-review.googlesource.com/c/go/+/454675 Reviewed-by: Michael Pratt <mpratt@google.com> Run-TryBot: Quim Muntal <quimmuntal@gmail.com> Reviewed-by: Cherry Mui <cherryyz@google.com> TryBot-Result: Gopher Robot <gobot@golang.org>
This commit is contained in:
parent
bb5ff5342d
commit
28f8dbd7b9
5 changed files with 84 additions and 57 deletions
|
|
@ -158,11 +158,11 @@ func progedit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
|
|||
}
|
||||
}
|
||||
|
||||
// Android and Win64 use a tls offset determined at runtime. Rewrite
|
||||
// Android and Windows use a tls offset determined at runtime. Rewrite
|
||||
// MOVQ TLS, BX
|
||||
// to
|
||||
// MOVQ runtime.tls_g(SB), BX
|
||||
if (isAndroid || (ctxt.Headtype == objabi.Hwindows && ctxt.Arch.Family == sys.AMD64)) &&
|
||||
if (isAndroid || ctxt.Headtype == objabi.Hwindows) &&
|
||||
(p.As == AMOVQ || p.As == AMOVL) && p.From.Type == obj.TYPE_REG && p.From.Reg == REG_TLS && p.To.Type == obj.TYPE_REG && REG_AX <= p.To.Reg && p.To.Reg <= REG_R15 {
|
||||
p.From.Type = obj.TYPE_MEM
|
||||
p.From.Name = obj.NAME_EXTERN
|
||||
|
|
@ -170,17 +170,23 @@ func progedit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
|
|||
p.From.Sym = ctxt.Lookup("runtime.tls_g")
|
||||
p.From.Index = REG_NONE
|
||||
if ctxt.Headtype == objabi.Hwindows {
|
||||
// Win64 requires an additional indirection
|
||||
// Windows requires an additional indirection
|
||||
// to retrieve the TLS pointer,
|
||||
// as runtime.tls_g contains the TLS offset from GS.
|
||||
// add
|
||||
// as runtime.tls_g contains the TLS offset from GS or FS.
|
||||
// on AMD64 add
|
||||
// MOVQ 0(BX)(GS*1), BX
|
||||
// on 386 add
|
||||
// MOVQ 0(BX)(FS*1), BX4
|
||||
q := obj.Appendp(p, newprog)
|
||||
q.As = p.As
|
||||
q.From = obj.Addr{}
|
||||
q.From.Type = obj.TYPE_MEM
|
||||
q.From.Reg = p.To.Reg
|
||||
q.From.Index = REG_GS
|
||||
if ctxt.Arch.Family == sys.AMD64 {
|
||||
q.From.Index = REG_GS
|
||||
} else {
|
||||
q.From.Index = REG_FS
|
||||
}
|
||||
q.From.Scale = 1
|
||||
q.From.Offset = 0
|
||||
q.To = p.To
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue