mirror of
https://github.com/golang/go
synced 2024-11-14 14:40:23 -07:00
liblink: use pc-relative addressing for all memory references in amd64 code
LGTM=rminnich, iant R=golang-codereviews, rminnich, iant CC=golang-codereviews, r https://golang.org/cl/125140043
This commit is contained in:
parent
d89cd24857
commit
ca85d572d6
@ -290,7 +290,6 @@ elfreloc1(Reloc *r, vlong sectoff)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case R_CALL:
|
case R_CALL:
|
||||||
case R_PCREL:
|
|
||||||
if(r->siz == 4) {
|
if(r->siz == 4) {
|
||||||
if(r->xsym->type == SDYNIMPORT)
|
if(r->xsym->type == SDYNIMPORT)
|
||||||
VPUT(R_X86_64_GOTPCREL | (uint64)elfsym<<32);
|
VPUT(R_X86_64_GOTPCREL | (uint64)elfsym<<32);
|
||||||
@ -300,6 +299,13 @@ elfreloc1(Reloc *r, vlong sectoff)
|
|||||||
return -1;
|
return -1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case R_PCREL:
|
||||||
|
if(r->siz == 4) {
|
||||||
|
VPUT(R_X86_64_PC32 | (uint64)elfsym<<32);
|
||||||
|
} else
|
||||||
|
return -1;
|
||||||
|
break;
|
||||||
|
|
||||||
case R_TLS:
|
case R_TLS:
|
||||||
if(r->siz == 4) {
|
if(r->siz == 4) {
|
||||||
if(flag_shared)
|
if(flag_shared)
|
||||||
@ -323,7 +329,7 @@ machoreloc1(Reloc *r, vlong sectoff)
|
|||||||
|
|
||||||
rs = r->xsym;
|
rs = r->xsym;
|
||||||
|
|
||||||
if(rs->type == SHOSTOBJ) {
|
if(rs->type == SHOSTOBJ || r->type == R_PCREL) {
|
||||||
if(rs->dynid < 0) {
|
if(rs->dynid < 0) {
|
||||||
diag("reloc %d to non-macho symbol %s type=%d", r->type, rs->name, rs->type);
|
diag("reloc %d to non-macho symbol %s type=%d", r->type, rs->name, rs->type);
|
||||||
return -1;
|
return -1;
|
||||||
@ -345,10 +351,13 @@ machoreloc1(Reloc *r, vlong sectoff)
|
|||||||
v |= MACHO_X86_64_RELOC_UNSIGNED<<28;
|
v |= MACHO_X86_64_RELOC_UNSIGNED<<28;
|
||||||
break;
|
break;
|
||||||
case R_CALL:
|
case R_CALL:
|
||||||
case R_PCREL:
|
|
||||||
v |= 1<<24; // pc-relative bit
|
v |= 1<<24; // pc-relative bit
|
||||||
v |= MACHO_X86_64_RELOC_BRANCH<<28;
|
v |= MACHO_X86_64_RELOC_BRANCH<<28;
|
||||||
break;
|
break;
|
||||||
|
case R_PCREL:
|
||||||
|
// NOTE: Only works with 'external' relocation. Forced above.
|
||||||
|
v |= 1<<24; // pc-relative bit
|
||||||
|
v |= MACHO_X86_64_RELOC_SIGNED<<28;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(r->siz) {
|
switch(r->siz) {
|
||||||
|
@ -281,9 +281,13 @@ relocsym(LSym *s)
|
|||||||
if(thechar == '6')
|
if(thechar == '6')
|
||||||
o = 0;
|
o = 0;
|
||||||
} else if(HEADTYPE == Hdarwin) {
|
} else if(HEADTYPE == Hdarwin) {
|
||||||
|
if(r->type == R_CALL) {
|
||||||
if(rs->type != SHOSTOBJ)
|
if(rs->type != SHOSTOBJ)
|
||||||
o += symaddr(rs) - rs->sect->vaddr;
|
o += symaddr(rs) - rs->sect->vaddr;
|
||||||
o -= r->off; // WTF?
|
o -= r->off; // relative to section offset, not symbol
|
||||||
|
} else {
|
||||||
|
o += r->siz;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
diag("unhandled pcrel relocation for %s", headstring);
|
diag("unhandled pcrel relocation for %s", headstring);
|
||||||
}
|
}
|
||||||
|
@ -1932,10 +1932,7 @@ oclass(Link *ctxt, Addr *a)
|
|||||||
switch(a->index) {
|
switch(a->index) {
|
||||||
case D_EXTERN:
|
case D_EXTERN:
|
||||||
case D_STATIC:
|
case D_STATIC:
|
||||||
if(ctxt->flag_shared || ctxt->headtype == Hnacl)
|
return Yiauto; // use pc-relative addressing
|
||||||
return Yiauto;
|
|
||||||
else
|
|
||||||
return Yi32; /* TO DO: Yi64 */
|
|
||||||
case D_AUTO:
|
case D_AUTO:
|
||||||
case D_PARAM:
|
case D_PARAM:
|
||||||
return Yiauto;
|
return Yiauto;
|
||||||
@ -2290,15 +2287,12 @@ vaddr(Link *ctxt, Addr *a, Reloc *r)
|
|||||||
r->sym = s;
|
r->sym = s;
|
||||||
r->add = v;
|
r->add = v;
|
||||||
v = 0;
|
v = 0;
|
||||||
if(ctxt->flag_shared || ctxt->headtype == Hnacl) {
|
r->type = R_PCREL;
|
||||||
if(s->type == STLSBSS) {
|
if(s->type == STLSBSS) {
|
||||||
r->xadd = r->add - r->siz;
|
r->xadd = r->add - r->siz;
|
||||||
r->type = R_TLS;
|
r->type = R_TLS;
|
||||||
r->xsym = s;
|
r->xsym = s;
|
||||||
} else
|
}
|
||||||
r->type = R_PCREL;
|
|
||||||
} else
|
|
||||||
r->type = R_ADDR;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case D_INDIR+D_TLS:
|
case D_INDIR+D_TLS:
|
||||||
@ -2333,13 +2327,6 @@ asmandsz(Link *ctxt, Addr *a, int r, int rex, int m64)
|
|||||||
switch(t) {
|
switch(t) {
|
||||||
default:
|
default:
|
||||||
goto bad;
|
goto bad;
|
||||||
case D_STATIC:
|
|
||||||
case D_EXTERN:
|
|
||||||
if(ctxt->flag_shared || ctxt->headtype == Hnacl)
|
|
||||||
goto bad;
|
|
||||||
t = D_NONE;
|
|
||||||
v = vaddr(ctxt, a, &rel);
|
|
||||||
break;
|
|
||||||
case D_AUTO:
|
case D_AUTO:
|
||||||
case D_PARAM:
|
case D_PARAM:
|
||||||
t = D_SP;
|
t = D_SP;
|
||||||
@ -2399,7 +2386,7 @@ asmandsz(Link *ctxt, Addr *a, int r, int rex, int m64)
|
|||||||
|
|
||||||
ctxt->rexflag |= (regrex[t] & Rxb) | rex;
|
ctxt->rexflag |= (regrex[t] & Rxb) | rex;
|
||||||
if(t == D_NONE || (D_CS <= t && t <= D_GS) || t == D_TLS) {
|
if(t == D_NONE || (D_CS <= t && t <= D_GS) || t == D_TLS) {
|
||||||
if((ctxt->flag_shared || ctxt->headtype == Hnacl) && t == D_NONE && (a->type == D_STATIC || a->type == D_EXTERN) || ctxt->asmode != 64) {
|
if(t == D_NONE && (a->type == D_STATIC || a->type == D_EXTERN) || ctxt->asmode != 64) {
|
||||||
*ctxt->andptr++ = (0 << 6) | (5 << 0) | (r << 3);
|
*ctxt->andptr++ = (0 << 6) | (5 << 0) | (r << 3);
|
||||||
goto putrelv;
|
goto putrelv;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user