summaryrefslogtreecommitdiff
path: root/src/cmd/ld
diff options
context:
space:
mode:
authorAnthony Martin <ality@pbrane.org>2011-06-07 14:26:16 -0400
committerAnthony Martin <ality@pbrane.org>2011-06-07 14:26:16 -0400
commit408c85ade1df523f30e51430526ff7ba81e96377 (patch)
tree7294629d2f89c7890d9bd19ebe6a6204b7e1d31b /src/cmd/ld
parent3ab759b1d703559e64f1b99f55821a4fb8c866a5 (diff)
downloadgo-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.h3
-rw-r--r--src/cmd/ld/symtab.c78
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