1
0
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:
Cherry Zhang 2019-04-09 12:10:27 -04:00
parent 016625c265
commit 68c664141c
3 changed files with 13 additions and 11 deletions

View File

@ -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)

View File

@ -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)

View File

@ -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
}