Commit ca85d572 authored by Russ Cox's avatar Russ Cox

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
parent d89cd248
...@@ -290,7 +290,6 @@ elfreloc1(Reloc *r, vlong sectoff) ...@@ -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);
...@@ -299,7 +298,14 @@ elfreloc1(Reloc *r, vlong sectoff) ...@@ -299,7 +298,14 @@ elfreloc1(Reloc *r, vlong sectoff)
} else } else
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) ...@@ -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) ...@@ -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) ...@@ -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(rs->type != SHOSTOBJ) if(r->type == R_CALL) {
o += symaddr(rs) - rs->sect->vaddr; if(rs->type != SHOSTOBJ)
o -= r->off; // WTF? o += symaddr(rs) - rs->sect->vaddr;
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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment