diff options
author | Gustavo Niemeyer <gustavo@niemeyer.net> | 2011-06-28 22:28:30 +0100 |
---|---|---|
committer | Gustavo Niemeyer <gustavo@niemeyer.net> | 2011-06-28 22:28:30 +0100 |
commit | cf143e9dbf6e3c5b0b2a97c76980b6d5bd5cc40f (patch) | |
tree | a8472d59b38c48c0601d1617fbe97227c1234b91 | |
parent | d0ac84fe404d345e25571ab0ee7596fc358d8b84 (diff) | |
download | go-cf143e9dbf6e3c5b0b2a97c76980b6d5bd5cc40f.tar.gz go-cf143e9dbf6e3c5b0b2a97c76980b6d5bd5cc40f.zip |
ld: fix ELF strip by removing overlap of sections
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
-rw-r--r-- | src/cmd/5l/asm.c | 31 | ||||
-rw-r--r-- | src/cmd/6l/asm.c | 29 | ||||
-rw-r--r-- | src/cmd/8l/asm.c | 29 | ||||
-rw-r--r-- | src/cmd/ld/data.c | 39 | ||||
-rw-r--r-- | src/cmd/ld/lib.c | 2 | ||||
-rw-r--r-- | src/cmd/ld/lib.h | 2 | ||||
-rw-r--r-- | src/cmd/ld/symtab.c | 2 |
7 files changed, 56 insertions, 78 deletions
diff --git a/src/cmd/5l/asm.c b/src/cmd/5l/asm.c index 4afed2b803..2c9e50d00e 100644 --- a/src/cmd/5l/asm.c +++ b/src/cmd/5l/asm.c @@ -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; diff --git a/src/cmd/6l/asm.c b/src/cmd/6l/asm.c index 4c04112b76..9136e03794 100644 --- a/src/cmd/6l/asm.c +++ b/src/cmd/6l/asm.c @@ -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; diff --git a/src/cmd/8l/asm.c b/src/cmd/8l/asm.c index a9a720af14..e1ccfb8a3d 100644 --- a/src/cmd/8l/asm.c +++ b/src/cmd/8l/asm.c @@ -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; diff --git a/src/cmd/ld/data.c b/src/cmd/ld/data.c index bdad58ff9a..f1132fc8bb 100644 --- a/src/cmd/ld/data.c +++ b/src/cmd/ld/data.c @@ -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); } diff --git a/src/cmd/ld/lib.c b/src/cmd/ld/lib.c index 04ee790a4e..77a62f5dec 100644 --- a/src/cmd/ld/lib.c +++ b/src/cmd/ld/lib.c @@ -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; diff --git a/src/cmd/ld/lib.h b/src/cmd/ld/lib.h index 4637131436..3479871955 100644 --- a/src/cmd/ld/lib.h +++ b/src/cmd/ld/lib.h @@ -40,6 +40,8 @@ enum SSTRING, SGOSTRING, SRODATA, + SSYMTAB, + SPCLNTAB, SDATA, SMACHO, /* Mach-O __nl_symbol_ptr */ SMACHOGOT, diff --git a/src/cmd/ld/symtab.c b/src/cmd/ld/symtab.c index e6dafab53a..60e146b354 100644 --- a/src/cmd/ld/symtab.c +++ b/src/cmd/ld/symtab.c @@ -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; |