]> Cypherpunks repositories - gostls13.git/commitdiff
ld: fix ELF strip by removing overlap of sections
authorGustavo Niemeyer <gustavo@niemeyer.net>
Tue, 28 Jun 2011 21:28:30 +0000 (22:28 +0100)
committerGustavo Niemeyer <gustavo@niemeyer.net>
Tue, 28 Jun 2011 21:28:30 +0000 (22:28 +0100)
The gosymtab and gopclntab sections were pointing to the proper
data, but that data was already owned by the rodata section.
Some ELF references explicitly prohibit multiple sections from
owning the same data, and strip behaves accordingly.

The data for these sections was moved to after rodata, and the
gosymtab and gopclntab sections now own their respective ranges.

This change makes strip happy both with and without -s being
provided at link time.  Note that it won't remove these sections
because they are still allocated, and that's by design since
they are necessary at runtime for generating proper backtraces
and similar introspection operations.

Unlike the previous behavior, -s will now maintain zero-sized
gosymtab and gopclntab sections.  This makes the implementation
slightly cleaner.

Fixes #1242.

NOTE: Tested on Linux amd64/386/arm only.

R=ality, rsc
CC=golang-dev
https://golang.org/cl/4639077

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

index 4afed2b8034bf95c686e0f97b922490b458a59eb..2c9e50d00e05ffa4fc5ce43247f1d46262544a2d 100644 (file)
@@ -68,9 +68,6 @@ enum {
        ElfStrText,
        ElfStrData,
        ElfStrBss,
-       ElfStrGosymcounts,
-       ElfStrGosymtab,
-       ElfStrGopclntab,
        ElfStrSymtab,
        ElfStrStrtab,
        ElfStrShstrtab,
@@ -160,12 +157,11 @@ doelf(void)
        elfstr[ElfStrEmpty] = addstring(shstrtab, "");
        elfstr[ElfStrText] = addstring(shstrtab, ".text");
        elfstr[ElfStrData] = addstring(shstrtab, ".data");
-       addstring(shstrtab, ".rodata");
        elfstr[ElfStrBss] = addstring(shstrtab, ".bss");
+       addstring(shstrtab, ".rodata");
+       addstring(shstrtab, ".gosymtab");
+       addstring(shstrtab, ".gopclntab");
        if(!debug['s']) {       
-               elfstr[ElfStrGosymcounts] = addstring(shstrtab, ".gosymcounts");
-               elfstr[ElfStrGosymtab] = addstring(shstrtab, ".gosymtab");
-               elfstr[ElfStrGopclntab] = addstring(shstrtab, ".gopclntab");
                elfstr[ElfStrSymtab] = addstring(shstrtab, ".symtab");
                elfstr[ElfStrStrtab] = addstring(shstrtab, ".strtab");
        }
@@ -307,10 +303,11 @@ asmb(void)
        seek(cout, sect->vaddr - segtext.vaddr + segtext.fileoff, 0);
        codeblk(sect->vaddr, sect->len);
 
-       /* output read-only data in text segment */
-       sect = segtext.sect->next;
-       seek(cout, sect->vaddr - segtext.vaddr + segtext.fileoff, 0);
-       datblk(sect->vaddr, sect->len);
+       /* output read-only data in text segment (rodata, gosymtab and pclntab) */
+       for(sect = sect->next; sect != nil; sect = sect->next) {
+               seek(cout, sect->vaddr - segtext.vaddr + segtext.fileoff, 0);
+               datblk(sect->vaddr, sect->len);
+       }
 
        if(debug['v'])
                Bprint(&bso, "%5.2f datblk\n", cputime());
@@ -572,18 +569,6 @@ asmb(void)
                        elfshbits(sect);
 
                if (!debug['s']) {
-                       sh = newElfShdr(elfstr[ElfStrGosymtab]);
-                       sh->type = SHT_PROGBITS;
-                       sh->flags = SHF_ALLOC;
-                       sh->addralign = 1;
-                       shsym(sh, lookup("symtab", 0));
-
-                       sh = newElfShdr(elfstr[ElfStrGopclntab]);
-                       sh->type = SHT_PROGBITS;
-                       sh->flags = SHF_ALLOC;
-                       sh->addralign = 1;
-                       shsym(sh, lookup("pclntab", 0));
-
                        sh = newElfShdr(elfstr[ElfStrSymtab]);
                        sh->type = SHT_SYMTAB;
                        sh->off = symo;
index 4c04112b76fe8d15f177121e5fcbc7b82127d54d..9136e03794c0831fc2be495eaf6964cbff4fa33e 100644 (file)
@@ -87,9 +87,6 @@ enum {
        ElfStrText,
        ElfStrData,
        ElfStrBss,
-       ElfStrGosymcounts,
-       ElfStrGosymtab,
-       ElfStrGopclntab,
        ElfStrShstrtab,
        ElfStrSymtab,
        ElfStrStrtab,
@@ -571,10 +568,9 @@ doelf(void)
        elfstr[ElfStrBss] = addstring(shstrtab, ".bss");
        addstring(shstrtab, ".elfdata");
        addstring(shstrtab, ".rodata");
+       addstring(shstrtab, ".gosymtab");
+       addstring(shstrtab, ".gopclntab");
        if(!debug['s']) {
-               elfstr[ElfStrGosymcounts] = addstring(shstrtab, ".gosymcounts");
-               elfstr[ElfStrGosymtab] = addstring(shstrtab, ".gosymtab");
-               elfstr[ElfStrGopclntab] = addstring(shstrtab, ".gopclntab");
                elfstr[ElfStrSymtab] = addstring(shstrtab, ".symtab");
                elfstr[ElfStrStrtab] = addstring(shstrtab, ".strtab");
                dwarfaddshstrings(shstrtab);
@@ -718,10 +714,11 @@ asmb(void)
        seek(cout, sect->vaddr - segtext.vaddr + segtext.fileoff, 0);
        codeblk(sect->vaddr, sect->len);
 
-       /* output read-only data in text segment */
-       sect = segtext.sect->next;
-       seek(cout, sect->vaddr - segtext.vaddr + segtext.fileoff, 0);
-       datblk(sect->vaddr, sect->len);
+       /* output read-only data in text segment (rodata, gosymtab and pclntab) */
+       for(sect = sect->next; sect != nil; sect = sect->next) {
+               seek(cout, sect->vaddr - segtext.vaddr + segtext.fileoff, 0);
+               datblk(sect->vaddr, sect->len);
+       }
 
        if(debug['v'])
                Bprint(&bso, "%5.2f datblk\n", cputime());
@@ -1013,18 +1010,6 @@ asmb(void)
                        elfshbits(sect);
 
                if (!debug['s']) {
-                       sh = newElfShdr(elfstr[ElfStrGosymtab]);
-                       sh->type = SHT_PROGBITS;
-                       sh->flags = SHF_ALLOC;
-                       sh->addralign = 1;
-                       shsym(sh, lookup("symtab", 0));
-
-                       sh = newElfShdr(elfstr[ElfStrGopclntab]);
-                       sh->type = SHT_PROGBITS;
-                       sh->flags = SHF_ALLOC;
-                       sh->addralign = 1;
-                       shsym(sh, lookup("pclntab", 0));
-
                        sh = newElfShdr(elfstr[ElfStrSymtab]);
                        sh->type = SHT_SYMTAB;
                        sh->off = symo;
index a9a720af1493ac3887fe33ae2ba5954d15f78746..e1ccfb8a3ddddcb301b944d22bb0139a2e976b7d 100644 (file)
@@ -83,9 +83,6 @@ enum {
        ElfStrText,
        ElfStrData,
        ElfStrBss,
-       ElfStrGosymcounts,
-       ElfStrGosymtab,
-       ElfStrGopclntab,
        ElfStrShstrtab,
        ElfStrSymtab,
        ElfStrStrtab,
@@ -531,10 +528,9 @@ doelf(void)
        elfstr[ElfStrBss] = addstring(shstrtab, ".bss");
        addstring(shstrtab, ".elfdata");
        addstring(shstrtab, ".rodata");
+       addstring(shstrtab, ".gosymtab");
+       addstring(shstrtab, ".gopclntab");
        if(!debug['s']) {
-               elfstr[ElfStrGosymcounts] = addstring(shstrtab, ".gosymcounts");
-               elfstr[ElfStrGosymtab] = addstring(shstrtab, ".gosymtab");
-               elfstr[ElfStrGopclntab] = addstring(shstrtab, ".gopclntab");
                elfstr[ElfStrSymtab] = addstring(shstrtab, ".symtab");
                elfstr[ElfStrStrtab] = addstring(shstrtab, ".strtab");
                dwarfaddshstrings(shstrtab);
@@ -679,10 +675,11 @@ asmb(void)
        seek(cout, sect->vaddr - segtext.vaddr + segtext.fileoff, 0);
        codeblk(sect->vaddr, sect->len);
 
-       /* output read-only data in text segment */
-       sect = segtext.sect->next;
-       seek(cout, sect->vaddr - segtext.vaddr + segtext.fileoff, 0);
-       datblk(sect->vaddr, sect->len);
+       /* output read-only data in text segment (rodata, gosymtab and pclntab) */
+       for(sect = sect->next; sect != nil; sect = sect->next) {
+               seek(cout, sect->vaddr - segtext.vaddr + segtext.fileoff, 0);
+               datblk(sect->vaddr, sect->len);
+       }
 
        if(debug['v'])
                Bprint(&bso, "%5.2f datblk\n", cputime());
@@ -1083,18 +1080,6 @@ asmb(void)
                        elfshbits(sect);
 
                if (!debug['s']) {
-                       sh = newElfShdr(elfstr[ElfStrGosymtab]);
-                       sh->type = SHT_PROGBITS;
-                       sh->flags = SHF_ALLOC;
-                       sh->addralign = 1;
-                       shsym(sh, lookup("symtab", 0));
-
-                       sh = newElfShdr(elfstr[ElfStrGopclntab]);
-                       sh->type = SHT_PROGBITS;
-                       sh->flags = SHF_ALLOC;
-                       sh->addralign = 1;
-                       shsym(sh, lookup("pclntab", 0));
-
                        sh = newElfShdr(elfstr[ElfStrSymtab]);
                        sh->type = SHT_SYMTAB;
                        sh->off = symo;
index bdad58ff9acce9acf8cf964b469155cae6d96b0d..f1132fc8bbb717d0b79263ee7895cf7f2da3eca9 100644 (file)
@@ -789,14 +789,34 @@ dodata(void)
        sect->vaddr = 0;
        datsize = 0;
        s = datap;
-       for(; s != nil && s->type < SDATA; s = s->next) {
+       for(; s != nil && s->type < SSYMTAB; s = s->next) {
                s->type = SRODATA;
                t = rnd(s->size, PtrSize);
                s->value = datsize;
                datsize += t;
        }
        sect->len = datsize - sect->vaddr;
-       
+
+       /* gosymtab */
+       sect = addsection(&segtext, ".gosymtab", 04);
+       sect->vaddr = datsize;
+       for(; s != nil && s->type < SPCLNTAB; s = s->next) {
+               s->type = SRODATA;
+               s->value = datsize;
+               datsize += s->size;
+       }
+       sect->len = datsize - sect->vaddr;
+
+       /* gopclntab */
+       sect = addsection(&segtext, ".gopclntab", 04);
+       sect->vaddr = datsize;
+       for(; s != nil && s->type < SDATA; s = s->next) {
+               s->type = SRODATA;
+               s->value = datsize;
+               datsize += s->size;
+       }
+       sect->len = datsize - sect->vaddr;
+
        /* data */
        datsize = 0;
        sect = addsection(&segdata, ".data", 06);
@@ -890,7 +910,7 @@ textaddress(void)
 void
 address(void)
 {
-       Section *s, *text, *data, *rodata;
+       Section *s, *text, *data, *rodata, *symtab, *pclntab;
        Sym *sym, *sub;
        uvlong va;
 
@@ -921,7 +941,9 @@ address(void)
        segdata.filelen = segdata.sect->len;    // assume .data is first
        
        text = segtext.sect;
-       rodata = segtext.sect->next;
+       rodata = text->next;
+       symtab = rodata->next;
+       pclntab = symtab->next;
        data = segdata.sect;
 
        for(sym = datap; sym != nil; sym = sym->next) {
@@ -938,12 +960,11 @@ address(void)
        xdefine("etext", STEXT, text->vaddr + text->len);
        xdefine("rodata", SRODATA, rodata->vaddr);
        xdefine("erodata", SRODATA, rodata->vaddr + rodata->len);
+       xdefine("symtab", SRODATA, symtab->vaddr);
+       xdefine("esymtab", SRODATA, symtab->vaddr + symtab->len);
+       xdefine("pclntab", SRODATA, pclntab->vaddr);
+       xdefine("epclntab", SRODATA, pclntab->vaddr + pclntab->len);
        xdefine("data", SBSS, data->vaddr);
        xdefine("edata", SBSS, data->vaddr + data->len);
        xdefine("end", SBSS, segdata.vaddr + segdata.len);
-
-       sym = lookup("pclntab", 0);
-       xdefine("epclntab", SRODATA, sym->value + sym->size);
-       sym = lookup("symtab", 0);
-       xdefine("esymtab", SRODATA, sym->value + sym->size);
 }
index 04ee790a4e008e2e7382cf58575db88a7c5a222a..77a62f5dec2fa36eec5f679a7e45e071e9f3dabe 100644 (file)
@@ -956,7 +956,7 @@ pclntab(void)
        uchar *bp;
        
        sym = lookup("pclntab", 0);
-       sym->type = SRODATA;
+       sym->type = SPCLNTAB;
        sym->reachable = 1;
        if(debug['s'])
                return;
index 4637131436c2d6f75c550fbabe78efc67ca6564d..3479871955a8443e93219bca10bf2d3750051b9f 100644 (file)
@@ -40,6 +40,8 @@ enum
        SSTRING,
        SGOSTRING,
        SRODATA,
+       SSYMTAB,
+       SPCLNTAB,
        SDATA,
        SMACHO, /* Mach-O __nl_symbol_ptr */
        SMACHOGOT,
index e6dafab53a32aa8d19cd51edbb5723d49ae9f04c..60e146b354eea9233d709dcdd5b6f560d554e4e0 100644 (file)
@@ -351,7 +351,7 @@ symtab(void)
        s->reachable = 1;
 
        symt = lookup("symtab", 0);
-       symt->type = SRODATA;
+       symt->type = SSYMTAB;
        symt->size = 0;
        symt->reachable = 1;