mirror of
https://github.com/golang/go
synced 2024-11-19 04:04:47 -07:00
cmd/ld: use TLS relocations on ELF systems in external linking mode
Fixes #7719. LGTM=iant R=iant CC=golang-codereviews https://golang.org/cl/87760050
This commit is contained in:
parent
90093f0634
commit
6f8b120869
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -2427,30 +2427,6 @@ 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))) {
|
||||
*ctxt->andptr++ = (0 << 6) | (reg[t] << 0) | (r << 3);
|
||||
return;
|
||||
}
|
||||
if(v >= -128 && v < 128 && (a->index != D_TLS || a->scale != 1)) {
|
||||
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;
|
||||
@ -2459,6 +2435,17 @@ asmandsz(Link *ctxt, Addr *a, int r, int rex, int m64)
|
||||
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 && rel.siz == 0) {
|
||||
ctxt->andptr[0] = (1 << 6) | (reg[t] << 0) | (r << 3);
|
||||
ctxt->andptr[1] = v;
|
||||
ctxt->andptr += 2;
|
||||
return;
|
||||
}
|
||||
*ctxt->andptr++ = (2 << 6) | (reg[t] << 0) | (r << 3);
|
||||
goto putrelv;
|
||||
}
|
||||
goto bad;
|
||||
|
@ -1857,35 +1857,6 @@ 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)) {
|
||||
*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)) {
|
||||
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;
|
||||
@ -1894,6 +1865,17 @@ asmand(Link *ctxt, Addr *a, int r)
|
||||
rel.add = v;
|
||||
v = 0;
|
||||
}
|
||||
if(v == 0 && rel.siz == 0 && t != D_BP) {
|
||||
*ctxt->andptr++ = (0 << 6) | (reg[t] << 0) | (r << 3);
|
||||
return;
|
||||
}
|
||||
if(v >= -128 && v < 128 && rel.siz == 0) {
|
||||
ctxt->andptr[0] = (1 << 6) | (reg[t] << 0) | (r << 3);
|
||||
ctxt->andptr[1] = v;
|
||||
ctxt->andptr += 2;
|
||||
return;
|
||||
}
|
||||
*ctxt->andptr++ = (2 << 6) | (reg[t] << 0) | (r << 3);
|
||||
goto putrelv;
|
||||
}
|
||||
goto bad;
|
||||
|
@ -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 $?
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user