diff options
| author | Russ Cox <rsc@golang.org> | 2013-03-10 19:07:16 -0700 |
|---|---|---|
| committer | Russ Cox <rsc@golang.org> | 2013-03-10 19:07:16 -0700 |
| commit | 9e13803ae1a66afdb03c7f584f70c07c8b4517a9 (patch) | |
| tree | d2f1e2c25e3d30e4843487ac9c4925ac08123283 /src/cmd/ld/data.c | |
| parent | cea78cb58ec53a564830450a9665d18a198ba266 (diff) | |
| download | go-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.c | 49 |
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; |
