aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/ld/data.c
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2013-03-10 19:07:16 -0700
committerRuss Cox <rsc@golang.org>2013-03-10 19:07:16 -0700
commit9e13803ae1a66afdb03c7f584f70c07c8b4517a9 (patch)
treed2f1e2c25e3d30e4843487ac9c4925ac08123283 /src/cmd/ld/data.c
parentcea78cb58ec53a564830450a9665d18a198ba266 (diff)
downloadgo-9e13803ae1a66afdb03c7f584f70c07c8b4517a9.tar.xz
cmd/ld: avoid redundant external relocation calculations
R=ken2, ken CC=golang-dev https://golang.org/cl/7483045
Diffstat (limited to 'src/cmd/ld/data.c')
-rw-r--r--src/cmd/ld/data.c49
1 files changed, 35 insertions, 14 deletions
diff --git a/src/cmd/ld/data.c b/src/cmd/ld/data.c
index e035942be7..ca6c5300bd 100644
--- a/src/cmd/ld/data.c
+++ b/src/cmd/ld/data.c
@@ -155,6 +155,7 @@ relocsym(Sym *s)
cursym = s;
memset(&p, 0, sizeof p);
for(r=s->r; r<s->r+s->nr; r++) {
+ r->done = 1;
off = r->off;
siz = r->siz;
if(off < 0 || off+siz > s->np) {
@@ -181,31 +182,51 @@ relocsym(Sym *s)
diag("unknown reloc %d", r->type);
break;
case D_ADDR:
- o = symaddr(r->sym) + r->add;
if(isobj && r->sym->type != SCONST) {
+ r->done = 0;
+
+ // set up addend for eventual relocation via outer symbol.
+ rs = r->sym;
+ r->xadd = r->add;
+ while(rs->outer != nil) {
+ r->xadd += symaddr(rs) - symaddr(rs->outer);
+ rs = rs->outer;
+ }
+ r->xsym = rs;
+
if(thechar == '6')
o = 0;
- else {
- // set up addend for eventual relocation via outer symbol
- rs = r->sym;
- while(rs->outer != nil)
- rs = rs->outer;
- o -= symaddr(rs);
- }
+ else
+ o = r->xadd;
+ break;
}
+ o = symaddr(r->sym) + r->add;
break;
case D_PCREL:
// r->sym can be null when CALL $(constant) is transformed from absolute PC to relative PC call.
- o = 0;
- if(r->sym)
- o += symaddr(r->sym);
- o += r->add - (s->value + r->off + r->siz);
- if(isobj && r->sym->type != SCONST && r->sym->sect != cursym->sect) {
+ if(isobj && r->sym && r->sym->type != SCONST && r->sym->sect != cursym->sect) {
+ r->done = 0;
+
+ // set up addend for eventual relocation via outer symbol.
+ rs = r->sym;
+ r->xadd = r->add;
+ while(rs->outer != nil) {
+ r->xadd += symaddr(rs) - symaddr(rs->outer);
+ rs = rs->outer;
+ }
+ r->xsym = rs;
+ r->xadd -= r->siz;
+
if(thechar == '6')
o = 0;
else
- o = r->add - r->siz;
+ o = r->xadd;
+ break;
}
+ o = 0;
+ if(r->sym)
+ o += symaddr(r->sym);
+ o += r->add - (s->value + r->off + r->siz);
break;
case D_SIZE:
o = r->sym->size + r->add;