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)
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
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)
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;
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))) {
+ if(a->index == D_TLS) {
+ memset(&rel, 0, sizeof rel);
+ rel.type = R_TLS_IE;
+ rel.siz = 4;
+ rel.sym = nil;
+ 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 && (a->index != D_TLS || a->scale != 1)) {
+ if(v >= -128 && v < 128 && rel.siz == 0) {
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;
- rel.siz = 4;
- rel.sym = nil;
- rel.add = v;
- v = 0;
- }
goto putrelv;
}
goto bad;
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)) {
+ if(a->index == D_TLS) {
+ memset(&rel, 0, sizeof rel);
+ rel.type = R_TLS_IE;
+ rel.siz = 4;
+ rel.sym = nil;
+ rel.add = v;
+ v = 0;
+ }
+ if(v == 0 && rel.siz == 0 && t != D_BP) {
*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)) {
+ if(v >= -128 && v < 128 && rel.siz == 0) {
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;
- rel.siz = 4;
- rel.sym = nil;
- rel.add = v;
- v = 0;
- }
goto putrelv;
}
goto bad;
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 $?