mirror of
https://github.com/golang/go
synced 2024-11-19 04:14:45 -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;
|
return -1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case R_TLS_LE:
|
||||||
|
if(r->siz == 4)
|
||||||
|
VPUT(R_X86_64_TPOFF32 | (uint64)elfsym<<32);
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
|
break;
|
||||||
|
|
||||||
case R_PCREL:
|
case R_PCREL:
|
||||||
if(r->siz == 4) {
|
if(r->siz == 4) {
|
||||||
if(r->xsym->type == SDYNIMPORT)
|
if(r->xsym->type == SDYNIMPORT)
|
||||||
|
@ -263,7 +263,8 @@ elfreloc1(Reloc *r, vlong sectoff)
|
|||||||
return -1;
|
return -1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case R_TLS:
|
case R_TLS_LE:
|
||||||
|
case R_TLS_IE:
|
||||||
if(r->siz == 4)
|
if(r->siz == 4)
|
||||||
LPUT(R_386_TLS_LE | elfsym<<8);
|
LPUT(R_386_TLS_LE | elfsym<<8);
|
||||||
else
|
else
|
||||||
|
@ -184,9 +184,30 @@ relocsym(LSym *s)
|
|||||||
o = r->add;
|
o = r->add;
|
||||||
break;
|
break;
|
||||||
case R_TLS_LE:
|
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;
|
o = ctxt->tlsoffset + r->add;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case R_TLS_IE:
|
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)
|
if(iself || ctxt->headtype == Hplan9)
|
||||||
o = ctxt->tlsoffset + r->add;
|
o = ctxt->tlsoffset + r->add;
|
||||||
else if(ctxt->headtype == Hwindows)
|
else if(ctxt->headtype == Hwindows)
|
||||||
|
@ -240,6 +240,7 @@ loadlib(void)
|
|||||||
gmsym->size = 2*PtrSize;
|
gmsym->size = 2*PtrSize;
|
||||||
gmsym->hide = 1;
|
gmsym->hide = 1;
|
||||||
gmsym->reachable = 1;
|
gmsym->reachable = 1;
|
||||||
|
ctxt->gmsym = gmsym;
|
||||||
|
|
||||||
// Now that we know the link mode, trim the dynexp list.
|
// Now that we know the link mode, trim the dynexp list.
|
||||||
x = CgoExportDynamic;
|
x = CgoExportDynamic;
|
||||||
|
@ -2427,30 +2427,6 @@ asmandsz(Link *ctxt, Addr *a, int r, int rex, int m64)
|
|||||||
goto putrelv;
|
goto putrelv;
|
||||||
}
|
}
|
||||||
if(t >= D_AX && t <= D_R15) {
|
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) {
|
if(a->index == D_TLS) {
|
||||||
memset(&rel, 0, sizeof rel);
|
memset(&rel, 0, sizeof rel);
|
||||||
rel.type = R_TLS_IE;
|
rel.type = R_TLS_IE;
|
||||||
@ -2459,6 +2435,17 @@ asmandsz(Link *ctxt, Addr *a, int r, int rex, int m64)
|
|||||||
rel.add = v;
|
rel.add = v;
|
||||||
v = 0;
|
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 putrelv;
|
||||||
}
|
}
|
||||||
goto bad;
|
goto bad;
|
||||||
|
@ -1857,35 +1857,6 @@ asmand(Link *ctxt, Addr *a, int r)
|
|||||||
goto putrelv;
|
goto putrelv;
|
||||||
}
|
}
|
||||||
if(t >= D_AX && t <= D_DI) {
|
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) {
|
if(a->index == D_TLS) {
|
||||||
memset(&rel, 0, sizeof rel);
|
memset(&rel, 0, sizeof rel);
|
||||||
rel.type = R_TLS_IE;
|
rel.type = R_TLS_IE;
|
||||||
@ -1894,6 +1865,17 @@ asmand(Link *ctxt, Addr *a, int r)
|
|||||||
rel.add = v;
|
rel.add = v;
|
||||||
v = 0;
|
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 putrelv;
|
||||||
}
|
}
|
||||||
goto bad;
|
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=external' || exit 1
|
||||||
go test -ldflags '-linkmode=auto' ../testtls || exit 1
|
go test -ldflags '-linkmode=auto' ../testtls || exit 1
|
||||||
go test -ldflags '-linkmode=external' ../testtls || exit 1
|
go test -ldflags '-linkmode=external' ../testtls || exit 1
|
||||||
|
go test -ldflags '-linkmode=external -extldflags "-static -pthread"' ../testtls || exit 1
|
||||||
esac
|
esac
|
||||||
) || exit $?
|
) || exit $?
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user