Commit 68c66414 authored by Cherry Zhang's avatar Cherry Zhang

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: default avatarBrad Fitzpatrick <bradfitz@golang.org>
parent 016625c2
......@@ -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)
......@@ -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
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment