The reason why strip breaks the ELF files generated by Go is that they
have overlapping sections. E.g.:
[Nr] Name Type Address Offset
Size EntSize Flags Link Info Align
[ 2] .rodata PROGBITS 000000000040e000 0000e000
00000000000134a0 0000000000000000 A 0 0 8
[ 5] .gosymtab PROGBITS 0000000000418048 00018048
0000000000009453 0000000000000000 A 0 0 1
[ 6] .gopclntab PROGBITS 00000000004164b8 000164b8
0000000000001b90 0000000000000000 A 0 0 1
Note how the .gosymtab and .gopclntab sections are both contained
within .rodata. This information is correct in the sense that this is
really the position of the respective data, but seems to be incorrect
in the sense that sections should not overlap. For instance, [1]
states:
"Sections in a file may not overlap. No byte in a file resides
in more than one section."
and the way binutils works seems to agree with that. strip is indeed
attempting to "fix" the file when it notices the overlap.
Here are a couple of suggestions for how we might fix this:
a) Drop these sections entirely. The data is already in .rodata, and
the only code depending on the reference from the gosymtab and
gopclntab sections in the tree is libmach and a test on debug/gosym.
Such logic could be changed to look at the symtab/pclntab symbols'
address and size instead.
b) Change ld so that it takes the data out of .rodata and turns
gosymtab and gopclntab into the owners. This involves more tweaks in
ld, but it would have the advantage of preserving the current client
API and also that these sections might be removable.
Which of these should I dig into?
[1] http://www.skyfree.org/linux/references/ELF_Format.pdf
--
Gustavo Niemeyer
http://niemeyer.net
http://niemeyer.net/blog
http://niemeyer.net/twitter
Even though it's convenient to get at the data in ELF
files with the .gosymtab section, this is the route I
would take.
Currently the Go symbol and line tables are found in
the following places (for each executable format):
ELF:
in both .gosymtab and .rodata
Mach-O:
in both the __TEXT segment and an
unused (and obsolete) GDB debugging
segment
Plan 9:
in the text segment
Windows:
in the .text section
If we added support in libmach for decoding the native
symbol table for each executable format, we could then
use the same procedure for each to find the Go symbol
and pclntab tables, namely:
· look up symtab and esymtab in the native table
· use those values to extract the Go table
· walk the new symbol table and create the Sym* list
· repeat for pclntab and epclntab
Anthony
Either of these is fine. I bet b is easier.
Russ
Sounds good. I'll push that forward.