summaryrefslogtreecommitdiff
path: root/src/cmd/ld/elf.c
diff options
context:
space:
mode:
authorMichael Stapelberg <michael@stapelberg.de>2013-03-23 11:28:53 +0100
committerMichael Stapelberg <michael@stapelberg.de>2013-03-23 11:28:53 +0100
commitb39e15dde5ec7b96c15da9faf4ab5892501c1aae (patch)
tree718cede1f6ca97d082c6c40b7dc3f4f6148253c0 /src/cmd/ld/elf.c
parent04b08da9af0c450d645ab7389d1467308cfc2db8 (diff)
downloadgolang-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.c54
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)