1
0
mirror of https://github.com/golang/go synced 2024-11-21 18:54:43 -07:00

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
This commit is contained in:
Gustavo Niemeyer 2011-06-28 22:28:30 +01:00
parent d0ac84fe40
commit cf143e9dbf
7 changed files with 56 additions and 78 deletions

View 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;

View 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;

View 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;

View 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);
}

View 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;

View File

@ -40,6 +40,8 @@ enum
SSTRING,
SGOSTRING,
SRODATA,
SSYMTAB,
SPCLNTAB,
SDATA,
SMACHO, /* Mach-O __nl_symbol_ptr */
SMACHOGOT,

View 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;