]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/internal/obj/x86: allow non-zero offset in TLS reference
authorCherry Zhang <cherryyz@google.com>
Tue, 9 Apr 2019 16:10:27 +0000 (12:10 -0400)
committerCherry Zhang <cherryyz@google.com>
Tue, 9 Apr 2019 18:57:21 +0000 (18:57 +0000)
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>
src/cmd/asm/internal/asm/testdata/386.s
src/cmd/asm/internal/asm/testdata/amd64.s
src/cmd/internal/obj/x86/asm6.go

index d524a4c8c120eba0002cd67baeebd309e797f3cd..e0855f5e4b66cf7d61f30bd81ab91dbb50d1fce8 100644 (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)
index 680d8eff388a509b28b566d3a657c17d4635be91..1dec7f4135a541c0c881ade29b900c281868ef7d 100644 (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)
index a81de43845e156dc61e80526a71faf158add4e0d..336446449b0e04e0f87938f351d26af340ce3201 100644 (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
                }