summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2014-08-18 21:06:56 -0400
committerRuss Cox <rsc@golang.org>2014-08-18 21:06:56 -0400
commit3a5410187cdd5d9ed93891cbdccda051246b7988 (patch)
tree572656a7e026ae5508936b2abe86c20d316fd465 /src
parent68789c6b9ca3988aeb86b7392e82d06252bc644e (diff)
downloadgo-3a5410187cdd5d9ed93891cbdccda051246b7988.tar.gz
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://codereview.appspot.com/125140043
Diffstat (limited to 'src')
-rw-r--r--src/cmd/6l/asm.c17
-rw-r--r--src/cmd/ld/data.c10
-rw-r--r--src/liblink/asm6.c29
3 files changed, 28 insertions, 28 deletions
diff --git a/src/cmd/6l/asm.c b/src/cmd/6l/asm.c
index e251e32ca..c7f6c65d0 100644
--- a/src/cmd/6l/asm.c
+++ b/src/cmd/6l/asm.c
@@ -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) {
diff --git a/src/cmd/ld/data.c b/src/cmd/ld/data.c
index f76ac0129..a988e807e 100644
--- a/src/cmd/ld/data.c
+++ b/src/cmd/ld/data.c
@@ -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);
}
diff --git a/src/liblink/asm6.c b/src/liblink/asm6.c
index fa329777d..e25c85053 100644
--- a/src/liblink/asm6.c
+++ b/src/liblink/asm6.c
@@ -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;
}