mirror of
https://github.com/golang/go
synced 2024-11-22 07: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,
|
ElfStrText,
|
||||||
ElfStrData,
|
ElfStrData,
|
||||||
ElfStrBss,
|
ElfStrBss,
|
||||||
ElfStrGosymcounts,
|
|
||||||
ElfStrGosymtab,
|
|
||||||
ElfStrGopclntab,
|
|
||||||
ElfStrSymtab,
|
ElfStrSymtab,
|
||||||
ElfStrStrtab,
|
ElfStrStrtab,
|
||||||
ElfStrShstrtab,
|
ElfStrShstrtab,
|
||||||
@ -160,12 +157,11 @@ doelf(void)
|
|||||||
elfstr[ElfStrEmpty] = addstring(shstrtab, "");
|
elfstr[ElfStrEmpty] = addstring(shstrtab, "");
|
||||||
elfstr[ElfStrText] = addstring(shstrtab, ".text");
|
elfstr[ElfStrText] = addstring(shstrtab, ".text");
|
||||||
elfstr[ElfStrData] = addstring(shstrtab, ".data");
|
elfstr[ElfStrData] = addstring(shstrtab, ".data");
|
||||||
addstring(shstrtab, ".rodata");
|
|
||||||
elfstr[ElfStrBss] = addstring(shstrtab, ".bss");
|
elfstr[ElfStrBss] = addstring(shstrtab, ".bss");
|
||||||
|
addstring(shstrtab, ".rodata");
|
||||||
|
addstring(shstrtab, ".gosymtab");
|
||||||
|
addstring(shstrtab, ".gopclntab");
|
||||||
if(!debug['s']) {
|
if(!debug['s']) {
|
||||||
elfstr[ElfStrGosymcounts] = addstring(shstrtab, ".gosymcounts");
|
|
||||||
elfstr[ElfStrGosymtab] = addstring(shstrtab, ".gosymtab");
|
|
||||||
elfstr[ElfStrGopclntab] = addstring(shstrtab, ".gopclntab");
|
|
||||||
elfstr[ElfStrSymtab] = addstring(shstrtab, ".symtab");
|
elfstr[ElfStrSymtab] = addstring(shstrtab, ".symtab");
|
||||||
elfstr[ElfStrStrtab] = addstring(shstrtab, ".strtab");
|
elfstr[ElfStrStrtab] = addstring(shstrtab, ".strtab");
|
||||||
}
|
}
|
||||||
@ -307,10 +303,11 @@ asmb(void)
|
|||||||
seek(cout, sect->vaddr - segtext.vaddr + segtext.fileoff, 0);
|
seek(cout, sect->vaddr - segtext.vaddr + segtext.fileoff, 0);
|
||||||
codeblk(sect->vaddr, sect->len);
|
codeblk(sect->vaddr, sect->len);
|
||||||
|
|
||||||
/* output read-only data in text segment */
|
/* output read-only data in text segment (rodata, gosymtab and pclntab) */
|
||||||
sect = segtext.sect->next;
|
for(sect = sect->next; sect != nil; sect = sect->next) {
|
||||||
seek(cout, sect->vaddr - segtext.vaddr + segtext.fileoff, 0);
|
seek(cout, sect->vaddr - segtext.vaddr + segtext.fileoff, 0);
|
||||||
datblk(sect->vaddr, sect->len);
|
datblk(sect->vaddr, sect->len);
|
||||||
|
}
|
||||||
|
|
||||||
if(debug['v'])
|
if(debug['v'])
|
||||||
Bprint(&bso, "%5.2f datblk\n", cputime());
|
Bprint(&bso, "%5.2f datblk\n", cputime());
|
||||||
@ -572,18 +569,6 @@ asmb(void)
|
|||||||
elfshbits(sect);
|
elfshbits(sect);
|
||||||
|
|
||||||
if (!debug['s']) {
|
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 = newElfShdr(elfstr[ElfStrSymtab]);
|
||||||
sh->type = SHT_SYMTAB;
|
sh->type = SHT_SYMTAB;
|
||||||
sh->off = symo;
|
sh->off = symo;
|
||||||
|
@ -87,9 +87,6 @@ enum {
|
|||||||
ElfStrText,
|
ElfStrText,
|
||||||
ElfStrData,
|
ElfStrData,
|
||||||
ElfStrBss,
|
ElfStrBss,
|
||||||
ElfStrGosymcounts,
|
|
||||||
ElfStrGosymtab,
|
|
||||||
ElfStrGopclntab,
|
|
||||||
ElfStrShstrtab,
|
ElfStrShstrtab,
|
||||||
ElfStrSymtab,
|
ElfStrSymtab,
|
||||||
ElfStrStrtab,
|
ElfStrStrtab,
|
||||||
@ -571,10 +568,9 @@ doelf(void)
|
|||||||
elfstr[ElfStrBss] = addstring(shstrtab, ".bss");
|
elfstr[ElfStrBss] = addstring(shstrtab, ".bss");
|
||||||
addstring(shstrtab, ".elfdata");
|
addstring(shstrtab, ".elfdata");
|
||||||
addstring(shstrtab, ".rodata");
|
addstring(shstrtab, ".rodata");
|
||||||
|
addstring(shstrtab, ".gosymtab");
|
||||||
|
addstring(shstrtab, ".gopclntab");
|
||||||
if(!debug['s']) {
|
if(!debug['s']) {
|
||||||
elfstr[ElfStrGosymcounts] = addstring(shstrtab, ".gosymcounts");
|
|
||||||
elfstr[ElfStrGosymtab] = addstring(shstrtab, ".gosymtab");
|
|
||||||
elfstr[ElfStrGopclntab] = addstring(shstrtab, ".gopclntab");
|
|
||||||
elfstr[ElfStrSymtab] = addstring(shstrtab, ".symtab");
|
elfstr[ElfStrSymtab] = addstring(shstrtab, ".symtab");
|
||||||
elfstr[ElfStrStrtab] = addstring(shstrtab, ".strtab");
|
elfstr[ElfStrStrtab] = addstring(shstrtab, ".strtab");
|
||||||
dwarfaddshstrings(shstrtab);
|
dwarfaddshstrings(shstrtab);
|
||||||
@ -718,10 +714,11 @@ asmb(void)
|
|||||||
seek(cout, sect->vaddr - segtext.vaddr + segtext.fileoff, 0);
|
seek(cout, sect->vaddr - segtext.vaddr + segtext.fileoff, 0);
|
||||||
codeblk(sect->vaddr, sect->len);
|
codeblk(sect->vaddr, sect->len);
|
||||||
|
|
||||||
/* output read-only data in text segment */
|
/* output read-only data in text segment (rodata, gosymtab and pclntab) */
|
||||||
sect = segtext.sect->next;
|
for(sect = sect->next; sect != nil; sect = sect->next) {
|
||||||
seek(cout, sect->vaddr - segtext.vaddr + segtext.fileoff, 0);
|
seek(cout, sect->vaddr - segtext.vaddr + segtext.fileoff, 0);
|
||||||
datblk(sect->vaddr, sect->len);
|
datblk(sect->vaddr, sect->len);
|
||||||
|
}
|
||||||
|
|
||||||
if(debug['v'])
|
if(debug['v'])
|
||||||
Bprint(&bso, "%5.2f datblk\n", cputime());
|
Bprint(&bso, "%5.2f datblk\n", cputime());
|
||||||
@ -1013,18 +1010,6 @@ asmb(void)
|
|||||||
elfshbits(sect);
|
elfshbits(sect);
|
||||||
|
|
||||||
if (!debug['s']) {
|
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 = newElfShdr(elfstr[ElfStrSymtab]);
|
||||||
sh->type = SHT_SYMTAB;
|
sh->type = SHT_SYMTAB;
|
||||||
sh->off = symo;
|
sh->off = symo;
|
||||||
|
@ -83,9 +83,6 @@ enum {
|
|||||||
ElfStrText,
|
ElfStrText,
|
||||||
ElfStrData,
|
ElfStrData,
|
||||||
ElfStrBss,
|
ElfStrBss,
|
||||||
ElfStrGosymcounts,
|
|
||||||
ElfStrGosymtab,
|
|
||||||
ElfStrGopclntab,
|
|
||||||
ElfStrShstrtab,
|
ElfStrShstrtab,
|
||||||
ElfStrSymtab,
|
ElfStrSymtab,
|
||||||
ElfStrStrtab,
|
ElfStrStrtab,
|
||||||
@ -531,10 +528,9 @@ doelf(void)
|
|||||||
elfstr[ElfStrBss] = addstring(shstrtab, ".bss");
|
elfstr[ElfStrBss] = addstring(shstrtab, ".bss");
|
||||||
addstring(shstrtab, ".elfdata");
|
addstring(shstrtab, ".elfdata");
|
||||||
addstring(shstrtab, ".rodata");
|
addstring(shstrtab, ".rodata");
|
||||||
|
addstring(shstrtab, ".gosymtab");
|
||||||
|
addstring(shstrtab, ".gopclntab");
|
||||||
if(!debug['s']) {
|
if(!debug['s']) {
|
||||||
elfstr[ElfStrGosymcounts] = addstring(shstrtab, ".gosymcounts");
|
|
||||||
elfstr[ElfStrGosymtab] = addstring(shstrtab, ".gosymtab");
|
|
||||||
elfstr[ElfStrGopclntab] = addstring(shstrtab, ".gopclntab");
|
|
||||||
elfstr[ElfStrSymtab] = addstring(shstrtab, ".symtab");
|
elfstr[ElfStrSymtab] = addstring(shstrtab, ".symtab");
|
||||||
elfstr[ElfStrStrtab] = addstring(shstrtab, ".strtab");
|
elfstr[ElfStrStrtab] = addstring(shstrtab, ".strtab");
|
||||||
dwarfaddshstrings(shstrtab);
|
dwarfaddshstrings(shstrtab);
|
||||||
@ -679,10 +675,11 @@ asmb(void)
|
|||||||
seek(cout, sect->vaddr - segtext.vaddr + segtext.fileoff, 0);
|
seek(cout, sect->vaddr - segtext.vaddr + segtext.fileoff, 0);
|
||||||
codeblk(sect->vaddr, sect->len);
|
codeblk(sect->vaddr, sect->len);
|
||||||
|
|
||||||
/* output read-only data in text segment */
|
/* output read-only data in text segment (rodata, gosymtab and pclntab) */
|
||||||
sect = segtext.sect->next;
|
for(sect = sect->next; sect != nil; sect = sect->next) {
|
||||||
seek(cout, sect->vaddr - segtext.vaddr + segtext.fileoff, 0);
|
seek(cout, sect->vaddr - segtext.vaddr + segtext.fileoff, 0);
|
||||||
datblk(sect->vaddr, sect->len);
|
datblk(sect->vaddr, sect->len);
|
||||||
|
}
|
||||||
|
|
||||||
if(debug['v'])
|
if(debug['v'])
|
||||||
Bprint(&bso, "%5.2f datblk\n", cputime());
|
Bprint(&bso, "%5.2f datblk\n", cputime());
|
||||||
@ -1083,18 +1080,6 @@ asmb(void)
|
|||||||
elfshbits(sect);
|
elfshbits(sect);
|
||||||
|
|
||||||
if (!debug['s']) {
|
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 = newElfShdr(elfstr[ElfStrSymtab]);
|
||||||
sh->type = SHT_SYMTAB;
|
sh->type = SHT_SYMTAB;
|
||||||
sh->off = symo;
|
sh->off = symo;
|
||||||
|
@ -789,7 +789,7 @@ dodata(void)
|
|||||||
sect->vaddr = 0;
|
sect->vaddr = 0;
|
||||||
datsize = 0;
|
datsize = 0;
|
||||||
s = datap;
|
s = datap;
|
||||||
for(; s != nil && s->type < SDATA; s = s->next) {
|
for(; s != nil && s->type < SSYMTAB; s = s->next) {
|
||||||
s->type = SRODATA;
|
s->type = SRODATA;
|
||||||
t = rnd(s->size, PtrSize);
|
t = rnd(s->size, PtrSize);
|
||||||
s->value = datsize;
|
s->value = datsize;
|
||||||
@ -797,6 +797,26 @@ dodata(void)
|
|||||||
}
|
}
|
||||||
sect->len = datsize - sect->vaddr;
|
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 */
|
/* data */
|
||||||
datsize = 0;
|
datsize = 0;
|
||||||
sect = addsection(&segdata, ".data", 06);
|
sect = addsection(&segdata, ".data", 06);
|
||||||
@ -890,7 +910,7 @@ textaddress(void)
|
|||||||
void
|
void
|
||||||
address(void)
|
address(void)
|
||||||
{
|
{
|
||||||
Section *s, *text, *data, *rodata;
|
Section *s, *text, *data, *rodata, *symtab, *pclntab;
|
||||||
Sym *sym, *sub;
|
Sym *sym, *sub;
|
||||||
uvlong va;
|
uvlong va;
|
||||||
|
|
||||||
@ -921,7 +941,9 @@ address(void)
|
|||||||
segdata.filelen = segdata.sect->len; // assume .data is first
|
segdata.filelen = segdata.sect->len; // assume .data is first
|
||||||
|
|
||||||
text = segtext.sect;
|
text = segtext.sect;
|
||||||
rodata = segtext.sect->next;
|
rodata = text->next;
|
||||||
|
symtab = rodata->next;
|
||||||
|
pclntab = symtab->next;
|
||||||
data = segdata.sect;
|
data = segdata.sect;
|
||||||
|
|
||||||
for(sym = datap; sym != nil; sym = sym->next) {
|
for(sym = datap; sym != nil; sym = sym->next) {
|
||||||
@ -938,12 +960,11 @@ address(void)
|
|||||||
xdefine("etext", STEXT, text->vaddr + text->len);
|
xdefine("etext", STEXT, text->vaddr + text->len);
|
||||||
xdefine("rodata", SRODATA, rodata->vaddr);
|
xdefine("rodata", SRODATA, rodata->vaddr);
|
||||||
xdefine("erodata", SRODATA, rodata->vaddr + rodata->len);
|
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("data", SBSS, data->vaddr);
|
||||||
xdefine("edata", SBSS, data->vaddr + data->len);
|
xdefine("edata", SBSS, data->vaddr + data->len);
|
||||||
xdefine("end", SBSS, segdata.vaddr + segdata.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;
|
uchar *bp;
|
||||||
|
|
||||||
sym = lookup("pclntab", 0);
|
sym = lookup("pclntab", 0);
|
||||||
sym->type = SRODATA;
|
sym->type = SPCLNTAB;
|
||||||
sym->reachable = 1;
|
sym->reachable = 1;
|
||||||
if(debug['s'])
|
if(debug['s'])
|
||||||
return;
|
return;
|
||||||
|
@ -40,6 +40,8 @@ enum
|
|||||||
SSTRING,
|
SSTRING,
|
||||||
SGOSTRING,
|
SGOSTRING,
|
||||||
SRODATA,
|
SRODATA,
|
||||||
|
SSYMTAB,
|
||||||
|
SPCLNTAB,
|
||||||
SDATA,
|
SDATA,
|
||||||
SMACHO, /* Mach-O __nl_symbol_ptr */
|
SMACHO, /* Mach-O __nl_symbol_ptr */
|
||||||
SMACHOGOT,
|
SMACHOGOT,
|
||||||
|
@ -351,7 +351,7 @@ symtab(void)
|
|||||||
s->reachable = 1;
|
s->reachable = 1;
|
||||||
|
|
||||||
symt = lookup("symtab", 0);
|
symt = lookup("symtab", 0);
|
||||||
symt->type = SRODATA;
|
symt->type = SSYMTAB;
|
||||||
symt->size = 0;
|
symt->size = 0;
|
||||||
symt->reachable = 1;
|
symt->reachable = 1;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user