mirror of
https://github.com/golang/go
synced 2024-11-22 01:14:40 -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:
parent
d0ac84fe40
commit
cf143e9dbf
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -40,6 +40,8 @@ enum
|
||||
SSTRING,
|
||||
SGOSTRING,
|
||||
SRODATA,
|
||||
SSYMTAB,
|
||||
SPCLNTAB,
|
||||
SDATA,
|
||||
SMACHO, /* Mach-O __nl_symbol_ptr */
|
||||
SMACHOGOT,
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user