]> Cypherpunks repositories - gostls13.git/commitdiff
ld: fix and simplify ELF symbol generation
authorAnthony Martin <ality@pbrane.org>
Tue, 7 Jun 2011 18:26:16 +0000 (14:26 -0400)
committerRuss Cox <rsc@golang.org>
Tue, 7 Jun 2011 18:26:16 +0000 (14:26 -0400)
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
https://golang.org/cl/4524075

src/cmd/5l/asm.c
src/cmd/6l/asm.c
src/cmd/8l/asm.c
src/cmd/ld/lib.h
src/cmd/ld/symtab.c

index 81c08e35354b4dd748308ea7207198d8ded2ac47..011e7f8424cbce65dfe202449510babd435fb24c 100644 (file)
@@ -34,8 +34,6 @@
 #include       "../ld/lib.h"
 #include       "../ld/elf.h"
 
-int32  OFFSET;
-
 static Prog *PP;
 
 char linuxdynld[] = "/lib/ld-linux.so.2";
@@ -295,7 +293,7 @@ asmb(void)
 {
        int32 t;
        int a, dynsym;
-       uint32 fo, symo, startva, elfsymo, elfstro, elfsymsize;
+       uint32 fo, symo, startva;
        ElfEhdr *eh;
        ElfPhdr *ph, *pph;
        ElfShdr *sh;
@@ -305,10 +303,6 @@ asmb(void)
                Bprint(&bso, "%5.2f asmb\n", cputime());
        Bflush(&bso);
 
-       elfsymsize = 0;
-       elfstro = 0;
-       elfsymo = 0;
-
        sect = segtext.sect;
        seek(cout, sect->vaddr - segtext.vaddr + segtext.fileoff, 0);
        codeblk(sect->vaddr, sect->len);
@@ -361,27 +355,22 @@ asmb(void)
                        debug['s'] = 1;
                        break;
                case Hplan9x32:
-                       OFFSET = HEADR+textsize+segdata.filelen;
-                       seek(cout, OFFSET, 0);
+                       symo = HEADR+segtext.len+segdata.filelen;
                        break;
                case Hnetbsd:
-                       OFFSET += rnd(segdata.filelen, 4096);
-                       seek(cout, OFFSET, 0);
+                       symo = rnd(segdata.filelen, 4096);
                        break;
                ElfSym:
                        symo = rnd(HEADR+segtext.filelen, INITRND)+segdata.filelen;
                        symo = rnd(symo, INITRND);
                        break;
                }
+               seek(cout, symo, 0);
                if(iself) {
                        if(debug['v'])
                               Bprint(&bso, "%5.2f elfsym\n", cputime());
-                       elfsymo = symo+8+symsize+lcsize;
-                       seek(cout, elfsymo, 0);
-                       asmelfsym32();
+                       asmelfsym();
                        cflush();
-                       elfstro = seek(cout, 0, 1);
-                       elfsymsize = elfstro - elfsymo;
                        ewrite(cout, elfstrdat, elfstrsize);
 
                        // if(debug['v'])
@@ -397,8 +386,7 @@ asmb(void)
        if(debug['v'])
                Bprint(&bso, "%5.2f header\n", cputime());
        Bflush(&bso);
-       OFFSET = 0;
-       seek(cout, OFFSET, 0);
+       seek(cout, 0L, 0);
        switch(HEADTYPE) {
        case Hnoheader: /* no header */
                break;
@@ -599,15 +587,15 @@ asmb(void)
 
                        sh = newElfShdr(elfstr[ElfStrSymtab]);
                        sh->type = SHT_SYMTAB;
-                       sh->off = elfsymo;
-                       sh->size = elfsymsize;
+                       sh->off = symo;
+                       sh->size = symsize;
                        sh->addralign = 4;
                        sh->entsize = 16;
                        sh->link = eh->shnum;   // link to strtab
 
                        sh = newElfShdr(elfstr[ElfStrStrtab]);
                        sh->type = SHT_STRTAB;
-                       sh->off = elfstro;
+                       sh->off = symo+symsize;
                        sh->size = elfstrsize;
                        sh->addralign = 1;
 
index 320f4c9e913264580f63dd4bfc0ed35201e3a5ce..4c04112b76fe8d15f177121e5fcbc7b82127d54d 100644 (file)
@@ -698,7 +698,7 @@ asmb(void)
 {
        int32 magic;
        int a, dynsym;
-       vlong vl, startva, symo, elfsymo, elfstro, elfsymsize, machlink;
+       vlong vl, startva, symo, machlink;
        ElfEhdr *eh;
        ElfPhdr *ph, *pph;
        ElfShdr *sh;
@@ -709,9 +709,6 @@ asmb(void)
        Bflush(&bso);
 
        elftextsh = 0;
-       elfsymsize = 0;
-       elfstro = 0;
-       elfsymo = 0;
        
        if(debug['v'])
                Bprint(&bso, "%5.2f codeblk\n", cputime());
@@ -790,36 +787,13 @@ asmb(void)
                        symo = rnd(symo, PEFILEALIGN);
                        break;
                }
+               seek(cout, symo, 0);
                switch(HEADTYPE) {
                default:
                        if(iself) {
-                               /*
-                                * the symbol information is stored as
-                                *      32-bit symbol table size
-                                *      32-bit line number table size
-                                *      symbol table
-                                *      line number table
-                                */
-                               seek(cout, symo+8, 0);
-                               if(debug['v'])
-                                       Bprint(&bso, "%5.2f sp\n", cputime());
-                               Bflush(&bso);
-                               if(debug['v'])
-                                       Bprint(&bso, "%5.2f pc\n", cputime());
-                               Bflush(&bso);
-                               if(!debug['s'])
-                                       strnput("", INITRND-(8+symsize+lcsize)%INITRND);
-                               cflush();
                                seek(cout, symo, 0);
-                               lputl(symsize);
-                               lputl(lcsize);
+                               asmelfsym();
                                cflush();
-                               elfsymo = symo+8+symsize+lcsize;
-                               seek(cout, elfsymo, 0);
-                               asmelfsym64();
-                               cflush();
-                               elfstro = seek(cout, 0, 1);
-                               elfsymsize = elfstro - elfsymo;
                                ewrite(cout, elfstrdat, elfstrsize);
 
                                if(debug['v'])
@@ -830,7 +804,6 @@ asmb(void)
                        break;
                case Hdarwin:
                case Hwindows:
-                       seek(cout, symo, 0);
                        if(debug['v'])
                               Bprint(&bso, "%5.2f dwarf\n", cputime());
 
@@ -1054,15 +1027,15 @@ asmb(void)
 
                        sh = newElfShdr(elfstr[ElfStrSymtab]);
                        sh->type = SHT_SYMTAB;
-                       sh->off = elfsymo;
-                       sh->size = elfsymsize;
+                       sh->off = symo;
+                       sh->size = symsize;
                        sh->addralign = 8;
                        sh->entsize = 24;
                        sh->link = eh->shnum;   // link to strtab
 
                        sh = newElfShdr(elfstr[ElfStrStrtab]);
                        sh->type = SHT_STRTAB;
-                       sh->off = elfstro;
+                       sh->off = symo+symsize;
                        sh->size = elfstrsize;
                        sh->addralign = 1;
 
@@ -1149,6 +1122,10 @@ genasmsym(void (*put)(Sym*, char*, int, vlong, vlong, int, Sym*))
        Auto *a;
        Sym *s;
 
+       s = lookup("etext", 0);
+       if(s->type == STEXT)
+               put(s, s->name, 'T', s->value, s->size, s->version, 0);
+
        for(s=allsym; s!=S; s=s->allsym) {
                if(s->hide)
                        continue;
index c426a88a4e77d3ada2ff105cc937d730539b2a47..cb900d28d01196fdae4ade74af1b5cf11d0e5bf1 100644 (file)
@@ -663,7 +663,7 @@ asmb(void)
 {
        int32 v, magic;
        int a, dynsym;
-       uint32 symo, startva, machlink, elfsymo, elfstro, elfsymsize;
+       uint32 symo, startva, machlink;
        ElfEhdr *eh;
        ElfPhdr *ph, *pph;
        ElfShdr *sh;
@@ -675,10 +675,6 @@ asmb(void)
                Bprint(&bso, "%5.2f asmb\n", cputime());
        Bflush(&bso);
 
-       elfsymsize = 0;
-       elfstro = 0;
-       elfsymo = 0;
-
        sect = segtext.sect;
        seek(cout, sect->vaddr - segtext.vaddr + segtext.fileoff, 0);
        codeblk(sect->vaddr, sect->len);
@@ -724,10 +720,10 @@ asmb(void)
                        if(iself)
                                goto Elfsym;
                case Hgarbunix:
-                       seek(cout, rnd(HEADR+segtext.filelen, 8192)+segdata.filelen, 0);
+                       symo = rnd(HEADR+segtext.filelen, 8192)+segdata.filelen;
                        break;
                case Hunixcoff:
-                       seek(cout, rnd(HEADR+segtext.filelen, INITRND)+segdata.filelen, 0);
+                       symo = rnd(HEADR+segtext.filelen, INITRND)+segdata.filelen;
                        break;
                case Hplan9x32:
                        symo = HEADR+segtext.filelen+segdata.filelen;
@@ -749,17 +745,14 @@ asmb(void)
                        symo = rnd(symo, PEFILEALIGN);
                        break;
                }
+               seek(cout, symo, 0);
                switch(HEADTYPE) {
                default:
                        if(iself) {
                                if(debug['v'])
                                       Bprint(&bso, "%5.2f elfsym\n", cputime());
-                               elfsymo = symo+8+symsize+lcsize;
-                               seek(cout, elfsymo, 0);
-                               asmelfsym32();
+                               asmelfsym();
                                cflush();
-                               elfstro = seek(cout, 0, 1);
-                               elfsymsize = elfstro - elfsymo;
                                ewrite(cout, elfstrdat, elfstrsize);
 
                                if(debug['v'])
@@ -768,10 +761,9 @@ asmb(void)
                        }
                        break;
                case Hplan9x32:
-                       seek(cout, symo, 0);
                        asmplan9sym();
                        cflush();
-                       
+
                        sym = lookup("pclntab", 0);
                        if(sym != nil) {
                                lcsize = sym->np;
@@ -783,7 +775,6 @@ asmb(void)
                        break;
                case Hdarwin:
                case Hwindows:
-                       seek(cout, symo, 0);
                        if(debug['v'])
                                Bprint(&bso, "%5.2f dwarf\n", cputime());
                        dwarfemitdebugsections();
@@ -1110,15 +1101,15 @@ asmb(void)
 
                        sh = newElfShdr(elfstr[ElfStrSymtab]);
                        sh->type = SHT_SYMTAB;
-                       sh->off = elfsymo;
-                       sh->size = elfsymsize;
+                       sh->off = symo;
+                       sh->size = symsize;
                        sh->addralign = 4;
                        sh->entsize = 16;
                        sh->link = eh->shnum;   // link to strtab
 
                        sh = newElfShdr(elfstr[ElfStrStrtab]);
                        sh->type = SHT_STRTAB;
-                       sh->off = elfstro;
+                       sh->off = symo+symsize;
                        sh->size = elfstrsize;
                        sh->addralign = 1;
 
index f69f5a35d43336f10b2baf5310f0e765b83a8836..dfd18fbff9044330619804dc7d433ddd5aa5f1a0 100644 (file)
@@ -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);
index da698fcc072c817dc101dd8c01f9f486e2ff9f07..e3093b2aac5081946023e0e434a8fb74b863c455 100644 (file)
@@ -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