mirror of
https://github.com/golang/go
synced 2024-11-24 01:10:12 -07:00
cmd/internal/obj/x86: allow non-zero offset in TLS reference
An instruction that references TLS, e.g. MOVQ 0(TLS), AX on some platforms (e.g. Android), or in shared mode, may be translated to (assuming TLS offset already loaded to CX) MOVQ 0(CX)(TLS*1), AX which in turns translates to movq %fs:(%rcx), %rax We have rejected non-zero offset for TLS reference, like 16(TLS). Actually, the instruction can take offset, i.e. it is a valid instruction for, e.g., movq %fs:16(%rcx),%rcx So, allow offset in TLS reference. Change-Id: Iaf1996bad7fe874e0c298ea441af5acb136a4028 Reviewed-on: https://go-review.googlesource.com/c/go/+/171151 Run-TryBot: Cherry Zhang <cherryyz@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
This commit is contained in:
parent
016625c265
commit
68c664141c
4
src/cmd/asm/internal/asm/testdata/386.s
vendored
4
src/cmd/asm/internal/asm/testdata/386.s
vendored
@ -89,6 +89,10 @@ label:
|
||||
loop:
|
||||
LOOP loop // LOOP
|
||||
|
||||
// Tests for TLS reference.
|
||||
MOVL (TLS), AX
|
||||
MOVL 8(TLS), DX
|
||||
|
||||
// LTYPE0 nonnon { outcode(int($1), &$2); }
|
||||
RET
|
||||
RET foo(SB)
|
||||
|
4
src/cmd/asm/internal/asm/testdata/amd64.s
vendored
4
src/cmd/asm/internal/asm/testdata/amd64.s
vendored
@ -143,6 +143,10 @@ loop:
|
||||
MOVB foo+32(SP)(CX*4), AH // 8a648c20
|
||||
MOVB foo+32323(SP)(CX*8), R9 // 448a8ccc437e0000
|
||||
|
||||
// Tests for TLS reference.
|
||||
MOVQ (TLS), AX
|
||||
MOVQ 8(TLS), DX
|
||||
|
||||
// LTYPE0 nonnon { outcode($1, &$2); }
|
||||
RET // c3
|
||||
RET foo(SB)
|
||||
|
@ -2345,17 +2345,14 @@ func prefixof(ctxt *obj.Link, a *obj.Addr) int {
|
||||
if ctxt.Arch.Family == sys.I386 {
|
||||
if a.Index == REG_TLS && ctxt.Flag_shared {
|
||||
// When building for inclusion into a shared library, an instruction of the form
|
||||
// MOVL 0(CX)(TLS*1), AX
|
||||
// MOVL off(CX)(TLS*1), AX
|
||||
// becomes
|
||||
// mov %gs:(%ecx), %eax
|
||||
// mov %gs:off(%ecx), %eax
|
||||
// which assumes that the correct TLS offset has been loaded into %ecx (today
|
||||
// there is only one TLS variable -- g -- so this is OK). When not building for
|
||||
// a shared library the instruction it becomes
|
||||
// mov 0x0(%ecx), $eax
|
||||
// mov 0x0(%ecx), %eax
|
||||
// and a R_TLS_LE relocation, and so does not require a prefix.
|
||||
if a.Offset != 0 {
|
||||
ctxt.Diag("cannot handle non-0 offsets to TLS")
|
||||
}
|
||||
return 0x65 // GS
|
||||
}
|
||||
return 0
|
||||
@ -2374,15 +2371,12 @@ func prefixof(ctxt *obj.Link, a *obj.Addr) int {
|
||||
case REG_TLS:
|
||||
if ctxt.Flag_shared && ctxt.Headtype != objabi.Hwindows {
|
||||
// When building for inclusion into a shared library, an instruction of the form
|
||||
// MOV 0(CX)(TLS*1), AX
|
||||
// MOV off(CX)(TLS*1), AX
|
||||
// becomes
|
||||
// mov %fs:(%rcx), %rax
|
||||
// mov %fs:off(%rcx), %rax
|
||||
// which assumes that the correct TLS offset has been loaded into %rcx (today
|
||||
// there is only one TLS variable -- g -- so this is OK). When not building for
|
||||
// a shared library the instruction does not require a prefix.
|
||||
if a.Offset != 0 {
|
||||
log.Fatalf("cannot handle non-0 offsets to TLS")
|
||||
}
|
||||
return 0x64
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user