From: Elias Naur Date: Mon, 3 Feb 2014 22:49:57 +0000 (-0800) Subject: liblink, cmd/5l: restore flag_shared X-Git-Tag: go1.3beta1~815 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=9ed5995cfe4c217c1291ced9c4a70334383df226;p=gostls13.git liblink, cmd/5l: restore flag_shared CL 56120043 fixed and cleaned up TLS on ARM after introducing liblink, but left flag_shared broken. This CL restores the (unsupported) flag_shared behaviour by simply rewriting access to $runtime.tlsgm(SB) with runtime.tlsgm(SB), to compensate for the extra indirection when going from the R_ARM_TLS_LE32 relocation to the R_ARM_TLS_IE32 relocation. Also, remove unnecessary symbol lookup left after 56120043. LGTM=iant R=iant, rsc CC=golang-codereviews https://golang.org/cl/57000043 --- diff --git a/src/cmd/5l/5.out.h b/src/cmd/5l/5.out.h index 99836cb7ff..16348a457e 100644 --- a/src/cmd/5l/5.out.h +++ b/src/cmd/5l/5.out.h @@ -279,7 +279,7 @@ enum D_PLT1 = (D_NONE+44), // R_ARM_PLT32, 2nd inst: add ip, ip, #0xNN000 D_PLT2 = (D_NONE+45), // R_ARM_PLT32, 3rd inst: ldr pc, [ip, #0xNNN]! D_CALL = (D_NONE+46), // R_ARM_PLT32/R_ARM_CALL/R_ARM_JUMP24, bl xxxxx or b yyyyy - D_TLS = (D_NONE+47), // R_ARM_TLS_LE32 + D_TLS = (D_NONE+47), // R_ARM_TLS_LE32/R_ARM_TLS_IE32 }; /* diff --git a/src/liblink/asm5.c b/src/liblink/asm5.c index d19283a197..02b6e8e465 100644 --- a/src/liblink/asm5.c +++ b/src/liblink/asm5.c @@ -1371,11 +1371,10 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na // Its "address" is the offset from the TLS thread pointer // to the thread-local g and m pointers. // Emit a TLS relocation instead of a standard one. - // The TLS flag_shared case is not tested and probably now wrong. if(rel->sym == ctxt->gmsym) { rel->type = D_TLS; if(ctxt->flag_shared) - rel->add += ctxt->pc - p->pcrel->pc - 8 - rel->siz; // TODO: probably wrong + rel->add += ctxt->pc - p->pcrel->pc - 8 - rel->siz; rel->xadd = rel->add; rel->xsym = rel->sym; } else if(ctxt->flag_shared) { diff --git a/src/liblink/obj5.c b/src/liblink/obj5.c index cda00b6432..2af23358fd 100644 --- a/src/liblink/obj5.c +++ b/src/liblink/obj5.c @@ -167,6 +167,21 @@ progedit(Link *ctxt, Prog *p) } break; } + + if(ctxt->flag_shared) { + // Shared libraries use R_ARM_TLS_IE32 instead of + // R_ARM_TLS_LE32, replacing the link time constant TLS offset in + // runtime.tlsgm with an address to a GOT entry containing the + // offset. Rewrite $runtime.tlsgm(SB) to runtime.tlsgm(SB) to + // compensate. + if(ctxt->gmsym == nil) + ctxt->gmsym = linklookup(ctxt, "runtime.tlsgm", 0); + + if(p->from.type == D_CONST && p->from.name == D_EXTERN && p->from.sym == ctxt->gmsym) + p->from.type = D_OREG; + if(p->to.type == D_CONST && p->to.name == D_EXTERN && p->to.sym == ctxt->gmsym) + p->to.type = D_OREG; + } } static Prog* @@ -225,8 +240,6 @@ addstacksplit(Link *ctxt, LSym *cursym) if(ctxt->symmorestack[0] == nil) ctxt->symmorestack[0] = linklookup(ctxt, "runtime.morestack", 0); - if(ctxt->gmsym == nil) - ctxt->gmsym = linklookup(ctxt, "runtime.tlsgm", 0); q = nil; ctxt->cursym = cursym; @@ -302,7 +315,6 @@ addstacksplit(Link *ctxt, LSym *cursym) * strip NOPs * expand RET * expand BECOME pseudo - * fixup TLS */ for(p = cursym->text; p != nil; p = p->link) {