]> Cypherpunks repositories - gostls13.git/commitdiff
liblink: remove use of linkmode on ARM
authorRuss Cox <rsc@golang.org>
Wed, 22 Jan 2014 00:46:34 +0000 (19:46 -0500)
committerRuss Cox <rsc@golang.org>
Wed, 22 Jan 2014 00:46:34 +0000 (19:46 -0500)
Now that liblink is compiled into the compilers and assemblers,
it must not refer to the "linkmode", since that is not known until
link time. This CL makes the ARM support no longer use linkmode,
which fixes a bug with cgo binaries that contain their own TLS
variables.

The x86 code must also remove linkmode; that is issue 7164.

Fixes #6992.

R=golang-codereviews, iant
CC=golang-codereviews
https://golang.org/cl/55160043

src/cmd/ld/data.c
src/liblink/asm5.c
src/liblink/obj5.c
src/pkg/runtime/asm_arm.s

index 0e3854fb57b79793b05f9ccfcb096f750aa6a21e..506bfd3b07ec74caa18a851209cedf9ac5efd917 100644 (file)
@@ -878,6 +878,14 @@ dodata(void)
                        growdatsize(&datsize, s);
                }
                sect->len = datsize;
+       } else {
+               // References to STLSBSS symbols may be in the binary
+               // but should not be used. Give them an invalid address
+               // so that any uses will fault. Using 1 instead of 0 so that
+               // if used as an offset on ARM it will result in an unaligned
+               // address and still cause a fault.
+               for(; s != nil && s->type == STLSBSS; s = s->next)
+                       s->value = 1;
        }
        
        if(s != nil) {
@@ -1127,7 +1135,8 @@ address(void)
 
        for(sym = datap; sym != nil; sym = sym->next) {
                ctxt->cursym = sym;
-               sym->value += sym->sect->vaddr;
+               if(sym->sect != nil)
+                       sym->value += sym->sect->vaddr;
                for(sub = sym->sub; sub != nil; sub = sub->sub)
                        sub->value += sym->value;
        }
index 923c059222e5768b0b8400f736921b921996c617..8d58fd38fee47b8a4bd87d04003f72c4c475474e 100644 (file)
@@ -368,7 +368,7 @@ static struct {
 static int     checkpool(Link*, Prog*, int);
 static int     flushpool(Link*, Prog*, int, int);
 static void    addpool(Link*, Prog*, Addr*);
-static void    asmout(Link*, Prog*, Optab*, int32*, LSym*);
+static void    asmout(Link*, Prog*, Optab*, int32*);
 static Optab*  oplook(Link*, Prog*);
 static int32   oprrr(Link*, int, int);
 static int32   olr(Link*, int32, int, int, int);
@@ -394,7 +394,7 @@ static      uchar   repop[ALAST];
 
 static Prog zprg = {
        .as = AGOK,
-       .scond = 14,
+       .scond = C_SCOND_NONE,
        .reg = NREG,
        .from = {
                .name = D_NONE,
@@ -458,7 +458,6 @@ span5(Link *ctxt, LSym *cursym)
        int m, bflag, i, v;
        int32 c, out[6];
        uchar *bp;
-       LSym *gmsym;
 
        p = cursym->text;
        if(p == nil || p->link == nil) // handle external functions and ELF section symbols
@@ -496,11 +495,11 @@ span5(Link *ctxt, LSym *cursym)
                        addpool(ctxt, p, &p->to);
                        break;
                case LPOOL:
-                       if ((p->scond&C_SCOND) == 14)
+                       if ((p->scond&C_SCOND) == C_SCOND_NONE)
                                flushpool(ctxt, p, 0, 0);
                        break;
                }
-               if(p->as==AMOVW && p->to.type==D_REG && p->to.reg==REGPC && (p->scond&C_SCOND) == 14)
+               if(p->as==AMOVW && p->to.type==D_REG && p->to.reg==REGPC && (p->scond&C_SCOND) == C_SCOND_NONE)
                        flushpool(ctxt, p, 0, 0);
                c += m;
        }
@@ -570,9 +569,8 @@ span5(Link *ctxt, LSym *cursym)
         * code references to be relocated too, and then
         * perhaps we'd be able to parallelize the span loop above.
         */
-       gmsym = nil;
-       if(ctxt->linkmode == LinkExternal)
-               gmsym = linklookup(ctxt, "runtime.tlsgm", 0);
+       if(ctxt->gmsym == nil)
+               ctxt->gmsym = linklookup(ctxt, "runtime.tlsgm", 0);
 
        p = cursym->text;
        ctxt->autosize = p->to.offset + 4;
@@ -583,7 +581,7 @@ span5(Link *ctxt, LSym *cursym)
                ctxt->pc = p->pc;
                ctxt->curp = p;
                o = oplook(ctxt, p);
-               asmout(ctxt, p, o, out, gmsym);
+               asmout(ctxt, p, o, out);
                for(i=0; i<o->size/4; i++) {
                        v = out[i];
                        *bp++ = v;
@@ -1213,7 +1211,7 @@ buildop(Link *ctxt)
 }
 
 static void
-asmout(Link *ctxt, Prog *p, Optab *o, int32 *out, LSym *gmsym)
+asmout(Link *ctxt, Prog *p, Optab *o, int32 *out)
 {
        int32 o1, o2, o3, o4, o5, o6, v;
        int r, rf, rt, rt2;
@@ -1366,7 +1364,7 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
                        rel->siz = 4;
                        rel->sym = p->to.sym;
                        rel->add = p->to.offset;
-                       if(rel->sym == gmsym) {
+                       if(rel->sym == ctxt->gmsym) {
                                rel->type = D_TLS;
                                if(ctxt->flag_shared)
                                        rel->add += ctxt->pc - p->pcrel->pc - 8 - rel->siz;
index 6505459b0fbdcfd50b3148172c7485a6f2f67424..665108cb979332760465cf43434c326c9ce6ea32 100644 (file)
@@ -37,7 +37,7 @@
 
 static Prog zprg = {
        .as = AGOK,
-       .scond = 14,
+       .scond = C_SCOND_NONE,
        .reg = NREG,
        .from = {
                .name = D_NONE,
@@ -207,8 +207,7 @@ addstacksplit(Link *ctxt, LSym *cursym)
                ctxt->symmorestack[0] = linklookup(ctxt, "runtime.morestack", 0);
        
        tlsfallback = linklookup(ctxt, "runtime.read_tls_fallback", 0);
-       ctxt->gmsym = nil;
-       if(ctxt->linkmode == LinkExternal)
+       if(ctxt->gmsym == nil)
                ctxt->gmsym = linklookup(ctxt, "runtime.tlsgm", 0);
        q = nil;
        
@@ -355,7 +354,9 @@ addstacksplit(Link *ctxt, LSym *cursym)
                        if((p->to.offset & 0xffff0fff) == 0xee1d0f70) {
                                if(ctxt->headtype == Hopenbsd) {
                                        p->as = ARET;
-                               } else if(ctxt->goarm < 7) {
+                                       break;
+                               }
+                               if(ctxt->goarm < 7) {
                                        // BL runtime.read_tls_fallback(SB)
                                        p->as = ABL;
                                        p->to.type = D_BRANCH;
@@ -363,63 +364,62 @@ addstacksplit(Link *ctxt, LSym *cursym)
                                        p->to.offset = 0;
                                        cursym->text->mark &= ~LEAF;
                                }
-                               if(ctxt->linkmode == LinkExternal) {
-                                       // runtime.tlsgm is relocated with R_ARM_TLS_LE32
-                                       // and $runtime.tlsgm will contain the TLS offset.
-                                       //
-                                       // MOV $runtime.tlsgm+ctxt->tlsoffset(SB), REGTMP
-                                       // ADD REGTMP, <reg>
-                                       //
-                                       // In shared mode, runtime.tlsgm is relocated with
-                                       // R_ARM_TLS_IE32 and runtime.tlsgm(SB) will point
-                                       // to the GOT entry containing the TLS offset.
-                                       //
-                                       // MOV runtime.tlsgm(SB), REGTMP
-                                       // ADD REGTMP, <reg>
-                                       // SUB -ctxt->tlsoffset, <reg>
-                                       //
-                                       // The SUB compensates for ctxt->tlsoffset
-                                       // used in runtime.save_gm and runtime.load_gm.
-                                       q = p;
-                                       p = appendp(ctxt, p);
-                                       p->as = AMOVW;
-                                       p->scond = 14;
-                                       p->reg = NREG;
-                                       if(ctxt->flag_shared) {
-                                               p->from.type = D_OREG;
-                                               p->from.offset = 0;
-                                       } else {
-                                               p->from.type = D_CONST;
-                                               p->from.offset = ctxt->tlsoffset;
-                                       }
-                                       p->from.sym = ctxt->gmsym;
-                                       p->from.name = D_EXTERN;
-                                       p->to.type = D_REG;
-                                       p->to.reg = REGTMP;
-                                       p->to.offset = 0;
+                               // runtime.tlsgm is relocated with R_ARM_TLS_LE32
+                               // and $runtime.tlsgm will contain the TLS offset.
+                               //
+                               // MOV $runtime.tlsgm+ctxt->tlsoffset(SB), REGTMP
+                               // ADD REGTMP, <reg>
+                               //
+                               // In shared mode, runtime.tlsgm is relocated with
+                               // R_ARM_TLS_IE32 and runtime.tlsgm(SB) will point
+                               // to the GOT entry containing the TLS offset.
+                               //
+                               // MOV runtime.tlsgm(SB), REGTMP
+                               // ADD REGTMP, <reg>
+                               // SUB -ctxt->tlsoffset, <reg>
+                               //
+                               // The SUB compensates for ctxt->tlsoffset
+                               // used in runtime.save_gm and runtime.load_gm.
+                               q = p;
+                               p = appendp(ctxt, p);
+                               p->as = AMOVW;
+                               p->scond = C_SCOND_NONE;
+                               p->reg = NREG;
+                               if(ctxt->flag_shared) {
+                                       p->from.type = D_OREG;
+                                       p->from.offset = 0;
+                               } else {
+                                       p->from.type = D_CONST;
+                                       p->from.offset = ctxt->tlsoffset;
+                               }
+                               p->from.sym = ctxt->gmsym;
+                               p->from.name = D_EXTERN;
+                               p->to.type = D_REG;
+                               p->to.reg = REGTMP;
+                               p->to.offset = 0;
 
+                               p = appendp(ctxt, p);
+                               p->as = AADD;
+                               p->scond = C_SCOND_NONE;
+                               p->reg = NREG;
+                               p->from.type = D_REG;
+                               p->from.reg = REGTMP;
+                               p->to.type = D_REG;
+                               p->to.reg = (q->to.offset & 0xf000) >> 12;
+                               p->to.offset = 0;
+
+                               if(ctxt->flag_shared) {
                                        p = appendp(ctxt, p);
-                                       p->as = AADD;
-                                       p->scond = 14;
+                                       p->as = ASUB;
+                                       p->scond = C_SCOND_NONE;
                                        p->reg = NREG;
-                                       p->from.type = D_REG;
-                                       p->from.reg = REGTMP;
+                                       p->from.type = D_CONST;
+                                       p->from.offset = -ctxt->tlsoffset;
                                        p->to.type = D_REG;
                                        p->to.reg = (q->to.offset & 0xf000) >> 12;
                                        p->to.offset = 0;
-
-                                       if(ctxt->flag_shared) {
-                                               p = appendp(ctxt, p);
-                                               p->as = ASUB;
-                                               p->scond = 14;
-                                               p->reg = NREG;
-                                               p->from.type = D_CONST;
-                                               p->from.offset = -ctxt->tlsoffset;
-                                               p->to.type = D_REG;
-                                               p->to.reg = (q->to.offset & 0xf000) >> 12;
-                                               p->to.offset = 0;
-                                       }
                                }
+                               break;
                        }
                }
                q = p;
@@ -984,7 +984,7 @@ loop:
                                i--;
                                continue;
                        }
-                       if(a == AB || (a == ARET && q->scond == 14) || a == ARFE || a == AUNDEF)
+                       if(a == AB || (a == ARET && q->scond == C_SCOND_NONE) || a == ARFE || a == AUNDEF)
                                goto copy;
                        if(q->pcond == nil || (q->pcond->mark&FOLL))
                                continue;
@@ -1005,7 +1005,7 @@ loop:
                                }
                                (*last)->link = r;
                                *last = r;
-                               if(a == AB || (a == ARET && q->scond == 14) || a == ARFE || a == AUNDEF)
+                               if(a == AB || (a == ARET && q->scond == C_SCOND_NONE) || a == ARFE || a == AUNDEF)
                                        return;
                                r->as = ABNE;
                                if(a == ABNE)
@@ -1031,7 +1031,7 @@ loop:
        p->mark |= FOLL;
        (*last)->link = p;
        *last = p;
-       if(a == AB || (a == ARET && p->scond == 14) || a == ARFE || a == AUNDEF){
+       if(a == AB || (a == ARET && p->scond == C_SCOND_NONE) || a == ARFE || a == AUNDEF){
                return;
        }
        if(p->pcond != nil)
index fa5540bdf0b90f8fd32cbaa3bd26668bd9c9bcc0..164cd802922ab51226e24354546fcd74aae37534 100644 (file)
@@ -627,14 +627,19 @@ _next:
 // Note: all three functions will clobber R0, and the last
 // two can be called from 5c ABI code.
 
-// g (R10) at 8(TP), m (R9) at 12(TP)
 TEXT runtime·save_gm(SB),NOSPLIT,$0
+       // NOTE: Liblink adds some instructions following the MRC
+       // to adjust R0 so that 8(R0) and 12(R0) are the TLS copies of
+       // the g and m registers. It's a bit too magical for its own good.
        MRC             15, 0, R0, C13, C0, 3 // Fetch TLS register
        MOVW    g, 8(R0)
        MOVW    m, 12(R0)
        RET
 
 TEXT runtime·load_gm(SB),NOSPLIT,$0
+       // NOTE: Liblink adds some instructions following the MRC
+       // to adjust R0 so that 8(R0) and 12(R0) are the TLS copies of
+       // the g and m registers. It's a bit too magical for its own good.
        MRC             15, 0, R0, C13, C0, 3 // Fetch TLS register
        MOVW    8(R0), g
        MOVW    12(R0), m
@@ -646,7 +651,6 @@ TEXT setmg_gcc<>(SB),NOSPLIT,$0
        MOVW    R1, g
        B               runtime·save_gm(SB)
 
-
 // TODO: share code with memeq?
 TEXT bytes·Equal(SB),NOSPLIT,$0
        MOVW    a_len+4(FP), R1