diff options
author | Michael Stapelberg <michael@stapelberg.de> | 2013-03-23 11:28:53 +0100 |
---|---|---|
committer | Michael Stapelberg <michael@stapelberg.de> | 2013-03-23 11:28:53 +0100 |
commit | b39e15dde5ec7b96c15da9faf4ab5892501c1aae (patch) | |
tree | 718cede1f6ca97d082c6c40b7dc3f4f6148253c0 /src/cmd/ld/elf.c | |
parent | 04b08da9af0c450d645ab7389d1467308cfc2db8 (diff) | |
download | golang-upstream/1.1_hg20130323.tar.gz |
Imported Upstream version 1.1~hg20130323upstream/1.1_hg20130323
Diffstat (limited to 'src/cmd/ld/elf.c')
-rw-r--r-- | src/cmd/ld/elf.c | 54 |
1 files changed, 19 insertions, 35 deletions
diff --git a/src/cmd/ld/elf.c b/src/cmd/ld/elf.c index 630906653..f5cce9c52 100644 --- a/src/cmd/ld/elf.c +++ b/src/cmd/ld/elf.c @@ -605,9 +605,7 @@ elfdynhash(void) if(sy->dynimpvers) need[sy->dynid] = addelflib(&needlib, sy->dynimplib, sy->dynimpvers); - name = sy->dynimpname; - if(name == nil) - name = sy->name; + name = sy->extname; hc = elfhash((uchar*)name); b = hc % nbucket; @@ -760,9 +758,9 @@ elfshbits(Section *sect) sh->flags |= SHF_EXECINSTR; if(sect->rwx & 2) sh->flags |= SHF_WRITE; - if(!isobj) + if(linkmode != LinkExternal) sh->addr = sect->vaddr; - sh->addralign = PtrSize; + sh->addralign = sect->align; sh->size = sect->len; sh->off = sect->seg->fileoff + sect->vaddr - sect->seg->vaddr; @@ -807,10 +805,9 @@ elfshreloc(Section *sect) void elfrelocsect(Section *sect, Sym *first) { - Sym *sym, *rs; + Sym *sym; int32 eaddr; Reloc *r; - int64 add; // If main section is SHT_NOBITS, nothing to relocate. // Also nothing to relocate in .shstrtab. @@ -836,28 +833,15 @@ elfrelocsect(Section *sect, Sym *first) cursym = sym; for(r = sym->r; r < sym->r+sym->nr; r++) { - // Ignore relocations handled by reloc already. - switch(r->type) { - case D_SIZE: + if(r->done) + continue; + if(r->xsym == nil) { + diag("missing xsym in relocation"); continue; - case D_ADDR: - case D_PCREL: - if(r->sym->type == SCONST) - continue; - break; - } - - add = r->add; - rs = r->sym; - while(rs->outer != nil) { - add += rs->value - rs->outer->value; - rs = rs->outer; } - - if(rs->elfsym == 0) - diag("reloc %d to non-elf symbol %s (rs=%s) %d", r->type, r->sym->name, rs->name, rs->type); - - if(elfreloc1(r, sym->value - sect->vaddr + r->off, rs->elfsym, add) < 0) + if(r->xsym->elfsym == 0) + diag("reloc %d to non-elf symbol %s (outer=%s) %d", r->type, r->sym->name, r->xsym->name, r->sym->type); + if(elfreloc1(r, sym->value+r->off - sect->vaddr) < 0) diag("unsupported obj reloc %d/%d to %s", r->type, r->siz, r->sym->name); } } @@ -915,7 +899,7 @@ doelf(void) addstring(shstrtab, ".gosymtab"); addstring(shstrtab, ".gopclntab"); - if(isobj) { + if(linkmode == LinkExternal) { debug['s'] = 0; debug['d'] = 1; @@ -1147,7 +1131,7 @@ asmbelf(vlong symo) resoff = ELFRESERVE; pph = nil; - if(isobj) { + if(linkmode == LinkExternal) { /* skip program headers */ eh->phoff = 0; eh->phentsize = 0; @@ -1408,7 +1392,7 @@ elfobj: for(sect=segdata.sect; sect!=nil; sect=sect->next) elfshbits(sect); - if(isobj) { + if(linkmode == LinkExternal) { for(sect=segtext.sect; sect!=nil; sect=sect->next) elfshreloc(sect); for(sect=segdata.sect; sect!=nil; sect=sect->next) @@ -1431,8 +1415,8 @@ elfobj: sh->size = elfstrsize; sh->addralign = 1; - // TODO(rsc): Enable for isobj too, once we know it works. - if(!isobj) + // TODO(rsc): Enable for linkmode == LinkExternal too, once we know it works. + if(linkmode != LinkExternal) dwarfaddelfheaders(); } @@ -1456,12 +1440,12 @@ elfobj: if(flag_shared) eh->type = ET_DYN; - else if(isobj) + else if(linkmode == LinkExternal) eh->type = ET_REL; else eh->type = ET_EXEC; - if(!isobj) + if(linkmode != LinkExternal) eh->entry = entryvalue(); eh->version = EV_CURRENT; @@ -1478,7 +1462,7 @@ elfobj: a += elfwriteshdrs(); if(!debug['d']) a += elfwriteinterp(); - if(!isobj) { + if(linkmode != LinkExternal) { if(HEADTYPE == Hnetbsd) a += elfwritenetbsdsig(); if(HEADTYPE == Hopenbsd) |