]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/ld: use TLS relocations on ELF systems in external linking mode
authorRuss Cox <rsc@golang.org>
Tue, 15 Apr 2014 19:13:52 +0000 (12:13 -0700)
committerRuss Cox <rsc@golang.org>
Tue, 15 Apr 2014 19:13:52 +0000 (12:13 -0700)
Fixes #7719.

LGTM=iant
R=iant
CC=golang-codereviews
https://golang.org/cl/87760050

src/cmd/6l/asm.c
src/cmd/8l/asm.c
src/cmd/ld/data.c
src/cmd/ld/lib.c
src/liblink/asm6.c
src/liblink/asm8.c
src/run.bash

index eced1a1441053e6a44e97af45da599bb1f1dfe1d..b70c752c445f4a1a6e7a8d6f1939f60cfb0b21fa 100644 (file)
@@ -281,6 +281,13 @@ elfreloc1(Reloc *r, vlong sectoff)
                        return -1;
                break;
 
+       case R_TLS_LE:
+               if(r->siz == 4)
+                       VPUT(R_X86_64_TPOFF32 | (uint64)elfsym<<32);
+               else
+                       return -1;
+               break;
+               
        case R_PCREL:
                if(r->siz == 4) {
                        if(r->xsym->type == SDYNIMPORT)
index 6bd2c1fdb7f39780cc034201973f8aa06772ab29..d933ed32b2c02e9885714401ef5794a85d7bfc1a 100644 (file)
@@ -263,7 +263,8 @@ elfreloc1(Reloc *r, vlong sectoff)
                        return -1;
                break;
        
-       case R_TLS:
+       case R_TLS_LE:
+       case R_TLS_IE:
                if(r->siz == 4)
                        LPUT(R_386_TLS_LE | elfsym<<8);
                else
index c822f5bd53a73faedd4e6a4c554cd8977c6b2769..a39243c85a107b3287787437cea2b3451246bf4c 100644 (file)
@@ -184,9 +184,30 @@ relocsym(LSym *s)
                                o = r->add;
                        break;
                case R_TLS_LE:
+                       if(linkmode == LinkExternal && iself) {
+                               r->done = 0;
+                               r->sym = ctxt->gmsym;
+                               r->xsym = ctxt->gmsym;
+                               r->xadd = r->add;
+                               o = 0;
+                               if(thechar != '6')
+                                       o = r->add;
+                               break;
+                       }
                        o = ctxt->tlsoffset + r->add;
                        break;
+
                case R_TLS_IE:
+                       if(linkmode == LinkExternal && iself) {
+                               r->done = 0;
+                               r->sym = ctxt->gmsym;
+                               r->xsym = ctxt->gmsym;
+                               r->xadd = r->add;
+                               o = 0;
+                               if(thechar != '6')
+                                       o = r->add;
+                               break;
+                       }
                        if(iself || ctxt->headtype == Hplan9)
                                o = ctxt->tlsoffset + r->add;
                        else if(ctxt->headtype == Hwindows)
index bfbdcd145b52872b4ca4c8fd06b9e107af23c8dc..81c53ef341db6863dfa39687fe9aeec708738cf7 100644 (file)
@@ -240,6 +240,7 @@ loadlib(void)
        gmsym->size = 2*PtrSize;
        gmsym->hide = 1;
        gmsym->reachable = 1;
+       ctxt->gmsym = gmsym;
 
        // Now that we know the link mode, trim the dynexp list.
        x = CgoExportDynamic;
index 104a08e21ed492eade47aa8be27e0522539504e3..b8029e10c3d3be3c977bccc6420c638f2e84fca4 100644 (file)
@@ -2427,38 +2427,25 @@ asmandsz(Link *ctxt, Addr *a, int r, int rex, int m64)
                goto putrelv;
        }
        if(t >= D_AX && t <= D_R15) {
-               // TODO: Remove Hwindows condition.
-               if(v == 0 && t != D_BP && t != D_R13 && (a->index != D_TLS || (ctxt->headtype == Hwindows && a->scale == 2))) {
+               if(a->index == D_TLS) {
+                       memset(&rel, 0, sizeof rel);
+                       rel.type = R_TLS_IE;
+                       rel.siz = 4;
+                       rel.sym = nil;
+                       rel.add = v;
+                       v = 0;
+               }
+               if(v == 0 && rel.siz == 0 && t != D_BP && t != D_R13) {
                        *ctxt->andptr++ = (0 << 6) | (reg[t] << 0) | (r << 3);
                        return;
                }
-               if(v >= -128 && v < 128 && (a->index != D_TLS || a->scale != 1)) {
+               if(v >= -128 && v < 128 && rel.siz == 0) {
                        ctxt->andptr[0] = (1 << 6) | (reg[t] << 0) | (r << 3);
-                       if(a->index == D_TLS) {
-                               Reloc *r;
-                               memset(&rel, 0, sizeof rel);
-                               rel.type = R_TLS_IE;
-                               rel.siz = 1;
-                               rel.sym = nil;
-                               rel.add = v;
-                               r = addrel(ctxt->cursym);
-                               *r = rel;
-                               r->off = ctxt->curp->pc + ctxt->andptr + 1 - ctxt->and;
-                               v = 0;
-                       }
                        ctxt->andptr[1] = v;
                        ctxt->andptr += 2;
                        return;
                }
                *ctxt->andptr++ = (2 << 6) | (reg[t] << 0) | (r << 3);
-               if(a->index == D_TLS) {
-                       memset(&rel, 0, sizeof rel);
-                       rel.type = R_TLS_IE;
-                       rel.siz = 4;
-                       rel.sym = nil;
-                       rel.add = v;
-                       v = 0;
-               }
                goto putrelv;
        }
        goto bad;
index 943db80f2f9fd1ef261efc923687e2bd8c5b918a..f28ac7cfe6b775caf965faa5990a68f89ce52f0e 100644 (file)
@@ -1857,43 +1857,25 @@ asmand(Link *ctxt, Addr *a, int r)
                goto putrelv;
        }
        if(t >= D_AX && t <= D_DI) {
-               // TODO(rsc): Remove the Hwindows test.
-               // As written it produces the same byte-identical output as the code it replaced.
-               if(v == 0 && rel.siz == 0 && t != D_BP && (a->index != D_TLS || ctxt->headtype == Hwindows)) {
+               if(a->index == D_TLS) {
+                       memset(&rel, 0, sizeof rel);
+                       rel.type = R_TLS_IE;
+                       rel.siz = 4;
+                       rel.sym = nil;
+                       rel.add = v;
+                       v = 0;
+               }
+               if(v == 0 && rel.siz == 0 && t != D_BP) {
                        *ctxt->andptr++ = (0 << 6) | (reg[t] << 0) | (r << 3);
                        return;
                }
-               // TODO(rsc): Change a->index tests to check D_TLS.
-               // Then remove the if statement inside the body.
-               // As written the code is clearly incorrect for external linking,
-               // but as written it produces the same byte-identical output as the code it replaced.
-               if(v >= -128 && v < 128 && rel.siz == 0 && (a->index != D_TLS || ctxt->headtype == Hwindows || a->scale != 1))  {
+               if(v >= -128 && v < 128 && rel.siz == 0)  {
                        ctxt->andptr[0] = (1 << 6) | (reg[t] << 0) | (r << 3);
-                       if(a->index == D_TLS) {
-                               Reloc *r;
-                               memset(&rel, 0, sizeof rel);
-                               rel.type = R_TLS_IE;
-                               rel.siz = 1;
-                               rel.sym = nil;
-                               rel.add = v;
-                               r = addrel(ctxt->cursym);
-                               *r = rel;
-                               r->off = ctxt->curp->pc + ctxt->andptr + 1 - ctxt->and;
-                               v = 0;
-                       }
                        ctxt->andptr[1] = v;
                        ctxt->andptr += 2;
                        return;
                }
                *ctxt->andptr++ = (2 << 6) | (reg[t] << 0) | (r << 3);
-               if(a->index == D_TLS) {
-                       memset(&rel, 0, sizeof rel);
-                       rel.type = R_TLS_IE;
-                       rel.siz = 4;
-                       rel.sym = nil;
-                       rel.add = v;
-                       v = 0;
-               }
                goto putrelv;
        }
        goto bad;
index dee30183f5002293f1ae9b75eded560c8476fa7a..3c0abd97b6483839bac146fa015313e75462f90e 100755 (executable)
@@ -131,6 +131,7 @@ dragonfly-386 | dragonfly-amd64 | freebsd-386 | freebsd-amd64 | linux-386 | linu
        go test -ldflags '-linkmode=external' || exit 1
        go test -ldflags '-linkmode=auto' ../testtls || exit 1
        go test -ldflags '-linkmode=external' ../testtls || exit 1
+       go test -ldflags '-linkmode=external -extldflags "-static -pthread"' ../testtls || exit 1
 esac
 ) || exit $?