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:
Russ Cox 2014-08-18 21:06:56 -04:00
parent d89cd24857
commit ca85d572d6
3 changed files with 28 additions and 28 deletions

View file

@ -290,7 +290,6 @@ elfreloc1(Reloc *r, vlong sectoff)
break;
case R_CALL:
case R_PCREL:
if(r->siz == 4) {
if(r->xsym->type == SDYNIMPORT)
VPUT(R_X86_64_GOTPCREL | (uint64)elfsym<<32);
@ -299,7 +298,14 @@ elfreloc1(Reloc *r, vlong sectoff)
} else
return -1;
break;
case R_PCREL:
if(r->siz == 4) {
VPUT(R_X86_64_PC32 | (uint64)elfsym<<32);
} else
return -1;
break;
case R_TLS:
if(r->siz == 4) {
if(flag_shared)
@ -323,7 +329,7 @@ machoreloc1(Reloc *r, vlong sectoff)
rs = r->xsym;
if(rs->type == SHOSTOBJ) {
if(rs->type == SHOSTOBJ || r->type == R_PCREL) {
if(rs->dynid < 0) {
diag("reloc %d to non-macho symbol %s type=%d", r->type, rs->name, rs->type);
return -1;
@ -345,10 +351,13 @@ machoreloc1(Reloc *r, vlong sectoff)
v |= MACHO_X86_64_RELOC_UNSIGNED<<28;
break;
case R_CALL:
case R_PCREL:
v |= 1<<24; // pc-relative bit
v |= MACHO_X86_64_RELOC_BRANCH<<28;
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) {

View file

@ -281,9 +281,13 @@ relocsym(LSym *s)
if(thechar == '6')
o = 0;
} else if(HEADTYPE == Hdarwin) {
if(rs->type != SHOSTOBJ)
o += symaddr(rs) - rs->sect->vaddr;
o -= r->off; // WTF?
if(r->type == R_CALL) {
if(rs->type != SHOSTOBJ)
o += symaddr(rs) - rs->sect->vaddr;
o -= r->off; // relative to section offset, not symbol
} else {
o += r->siz;
}
} else {
diag("unhandled pcrel relocation for %s", headstring);
}

View file

@ -1932,10 +1932,7 @@ oclass(Link *ctxt, Addr *a)
switch(a->index) {
case D_EXTERN:
case D_STATIC:
if(ctxt->flag_shared || ctxt->headtype == Hnacl)
return Yiauto;
else
return Yi32; /* TO DO: Yi64 */
return Yiauto; // use pc-relative addressing
case D_AUTO:
case D_PARAM:
return Yiauto;
@ -2290,15 +2287,12 @@ vaddr(Link *ctxt, Addr *a, Reloc *r)
r->sym = s;
r->add = v;
v = 0;
if(ctxt->flag_shared || ctxt->headtype == Hnacl) {
if(s->type == STLSBSS) {
r->xadd = r->add - r->siz;
r->type = R_TLS;
r->xsym = s;
} else
r->type = R_PCREL;
} else
r->type = R_ADDR;
r->type = R_PCREL;
if(s->type == STLSBSS) {
r->xadd = r->add - r->siz;
r->type = R_TLS;
r->xsym = s;
}
break;
case D_INDIR+D_TLS:
@ -2333,13 +2327,6 @@ asmandsz(Link *ctxt, Addr *a, int r, int rex, int m64)
switch(t) {
default:
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_PARAM:
t = D_SP;
@ -2399,7 +2386,7 @@ asmandsz(Link *ctxt, Addr *a, int r, int rex, int m64)
ctxt->rexflag |= (regrex[t] & Rxb) | rex;
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);
goto putrelv;
}