Commit 9ed5995c authored by Elias Naur's avatar Elias Naur Committed by Ian Lance Taylor

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
parent 1dd4da14
......@@ -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
};
/*
......
......@@ -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) {
......
......@@ -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) {
......
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