diff options
author | Anthony Martin <ality@pbrane.org> | 2011-06-07 14:26:16 -0400 |
---|---|---|
committer | Anthony Martin <ality@pbrane.org> | 2011-06-07 14:26:16 -0400 |
commit | 408c85ade1df523f30e51430526ff7ba81e96377 (patch) | |
tree | 7294629d2f89c7890d9bd19ebe6a6204b7e1d31b /src/cmd/ld | |
parent | 3ab759b1d703559e64f1b99f55821a4fb8c866a5 (diff) | |
download | go-408c85ade1df523f30e51430526ff7ba81e96377.tar.gz |
ld: fix and simplify ELF symbol generation
I started looking at this code because the nm in GNU
binutils was ignoring the first symbol in the .symtab
section. Apparently, the System V ABI reserves the
first entry and requires all fields inside to be set
to zero.
The list of changes is as follows:
? reserve the first symbol entry (as noted above)
? fix the section indices for .data and .bss symbols
? factor out common code for Elf32 and Elf64
? remove the special case for elfsymo in [568]l/asm.c:/^asmb
? add the "etext" symbol in 6l
? add static symbols
R=rsc
CC=golang-dev
http://codereview.appspot.com/4524075
Committer: Russ Cox <rsc@golang.org>
Diffstat (limited to 'src/cmd/ld')
-rw-r--r-- | src/cmd/ld/lib.h | 3 | ||||
-rw-r--r-- | src/cmd/ld/symtab.c | 78 |
2 files changed, 33 insertions, 48 deletions
diff --git a/src/cmd/ld/lib.h b/src/cmd/ld/lib.h index f69f5a35d..dfd18fbff 100644 --- a/src/cmd/ld/lib.h +++ b/src/cmd/ld/lib.h @@ -186,8 +186,7 @@ vlong addsize(Sym*, Sym*); vlong adduint8(Sym*, uint8); vlong adduint16(Sym*, uint16); void asmsym(void); -void asmelfsym32(void); -void asmelfsym64(void); +void asmelfsym(void); void asmplan9sym(void); void strnput(char*, int); void dodata(void); diff --git a/src/cmd/ld/symtab.c b/src/cmd/ld/symtab.c index da698fcc0..e3093b2aa 100644 --- a/src/cmd/ld/symtab.c +++ b/src/cmd/ld/symtab.c @@ -61,49 +61,35 @@ putelfstr(char *s) } void -putelfsym64(Sym *x, char *s, int t, vlong addr, vlong size, int ver, Sym *go) +putelfsyment(int off, vlong addr, vlong size, int info, int shndx) { - int bind, type, shndx, stroff; - - bind = STB_GLOBAL; - switch(t) { - default: - return; - case 'T': - type = STT_FUNC; - shndx = elftextsh + 0; - break; - case 'D': - type = STT_OBJECT; - shndx = elftextsh + 1; + switch(thechar) { + case '6': + LPUT(off); + cput(info); + cput(0); + WPUT(shndx); + VPUT(addr); + VPUT(size); + symsize += ELF64SYMSIZE; break; - case 'B': - type = STT_OBJECT; - shndx = elftextsh + 2; + default: + LPUT(off); + LPUT(addr); + LPUT(size); + cput(info); + cput(0); + WPUT(shndx); + symsize += ELF32SYMSIZE; break; } - - stroff = putelfstr(s); - LPUT(stroff); // string - cput((bind<<4)|(type&0xF)); - cput(0); - WPUT(shndx); - VPUT(addr); - VPUT(size); } void -asmelfsym64(void) +putelfsym(Sym *x, char *s, int t, vlong addr, vlong size, int ver, Sym *go) { - genasmsym(putelfsym64); -} + int bind, type, shndx, off; -void -putelfsym32(Sym *x, char *s, int t, vlong addr, vlong size, int ver, Sym *go) -{ - int bind, type, shndx, stroff; - - bind = STB_GLOBAL; switch(t) { default: return; @@ -113,27 +99,27 @@ putelfsym32(Sym *x, char *s, int t, vlong addr, vlong size, int ver, Sym *go) break; case 'D': type = STT_OBJECT; - shndx = elftextsh + 1; + if((x->type&~SSUB) == SRODATA) + shndx = elftextsh + 1; + else + shndx = elftextsh + 2; break; case 'B': type = STT_OBJECT; - shndx = elftextsh + 2; + shndx = elftextsh + 3; break; } - - stroff = putelfstr(s); - LPUT(stroff); // string - LPUT(addr); - LPUT(size); - cput((bind<<4)|(type&0xF)); - cput(0); - WPUT(shndx); + bind = ver ? STB_LOCAL : STB_GLOBAL; + off = putelfstr(s); + putelfsyment(off, addr, size, (bind<<4)|(type&0xf), shndx); } void -asmelfsym32(void) +asmelfsym(void) { - genasmsym(putelfsym32); + // the first symbol entry is reserved + putelfsyment(0, 0, 0, (STB_LOCAL<<4)|STT_NOTYPE, 0); + genasmsym(putelfsym); } void |