You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
What steps will reproduce the problem?
1. compile a Go app (such as http://codepad.org/KFcgHcF6) in the usual manner
2. run 'strip' on the resulting binary: strip yourBinary
3. attempt to run the binary: ./yourBinary
4. experience a Segmentation fault
What is the expected output?
everything but a Segmentation fault
What do you see instead?
Segmentation fault
Which compiler are you using (5g, 6g, 8g, gccgo)?
8g
Which operating system are you using?
Linux (Ubuntu 10.04)
Which revision are you using? (hg identify)
4d5b08163921+ tip
Please provide any additional information below.
version of strip: 2.20.1-system.20100303
Comment 7:
I don't think that elfutils is a safe way to determine whether an ELF Binary is
"wellformed".
Consider this C Code:
#include <stdio.h>
int main()
{
printf("Hello World\n");
return 0;
}
Now, after running elflint:
section [10] '.rel.plt': relocation 0: offset out of bounds
section [10] '.rel.plt': relocation 1: offset out of bounds
section [10] '.rel.plt': relocation 2: offset out of bounds
section [27] '.symtab': _GLOBAL_OFFSET_TABLE_ symbol size 0 does not match .got.plt section size 24
section [27] '.symtab': _DYNAMIC symbol size 0 does not match dynamic segment size 200
And now, the same with Go:
package main
import "fmt"
func main() {
fmt.Printf("Hello world\n")
}
And elflint:
PHDR segment not contained in a loaded segment
section [ 1] '.interp': alloc flag set but section not in any loaded segment
section [12] '.rodata' has wrong flags: expected ALLOC and possibly MERGE|STRINGS, is WRITE|ALLOC
I suppose that elflint actually has a hardcoded pattern for ELF Binaries, or some such...
I wrote a small program (in python, sry) that will run readelf -S and sort the results
so that the issues might be more visible. It prints out zero sized sections too, but
feel free ignore those.
On tutorial hello world, with 6g pulled in 2011-03-16, the results are as follows (prior
to even running strip):
./parse-sections.py 6.out
SectName VMAddress Size(B) Errors
.interp 0x00400be4 28
.text 0x00400c00 237618
.rela.plt 0x0043b000 0 ZERO SIZED SECTION
.rela 0x0043b000 0 OVERLAPS WITH PREVIOUS, ZERO SIZED SECTION
.dynstr 0x0043b000 4 OVERLAPS WITH PREVIOUS
.rodata 0x0043b000 788232 OVERLAPS WITH PREVIOUS
.plt 0x0043b004 16 OVERLAPS WITH PREVIOUS
.hash 0x0043b014 20
.dynsym 0x0043b028 24
.dynamic 0x0043b040 224
.shstrtab 0x0043b120 340
.gopclntab 0x0048f9a8 21080
.gosymtab 0x00494c00 420616
.got 0x004fc000 0 ZERO SIZED SECTION
.data 0x004fc000 8160 OVERLAPS WITH PREVIOUS
.got.plt 0x004fc118 24 OVERLAPS WITH PREVIOUS
.bss 0x004fdfe0 33647768
Some of the overlaps are quite serious in range. These will certainly trigger the
warnings of libbfd (that strip uses).
The silly little python script I wrote can be found at
http://iohazard.net/pub/go/parse-sections.py .
It'd be nice to see the generated ELFs getting along a bit better with
binutils/elfutils. I may start some ant-paced janitoring tasks towards
that if no one is against it.
Yes, unfortunately I was testing with a non-dynamic binary.
A similar fix will have to be made for dynamic ones, and I'll
work on it next.
A new bug was opened to track this:
https://golang.org/issue/2022
The major issue reported by elflint is not to do with symbol lengths and section
alignment, but with the PHDR segment:
PHDR segment not contained in a loaded segment
This is, as far as I can tell, the only fatal error that the tools I want to use (paxctl
notably) report, the others being icky but workaroundable.
A quick analysis of a static Go binary suggests that the PHDR section is the last in the
section header table, after all the loadable sections containing the executable
text/data. However, the ELF specs that I've been looking at specify that the PHDR
section entry in the section header table should appear /before/ any sections marked
loadable.
I'm fairly sure there's more constraints on the PHDR section that I haven't found yet,
but that's the braindump of my current attempts to make paxctl work with Go programs, if
anyone can beat me to a patch that makes that fatal error go away.
I have been fixing these other elflint warnings as well, and even though
I've not debugged the PHDR issue yet I have a few other in the pipeline
which I know the cause and the fix. I've just been a bit slow due to
projects at Canonical taking my time.
Note that this one bug we're discussing here is about strip working. It
will be closed without the PHDR issue being addressed, so feel free to
open another one if that's important for you.
Aha, I see. The bug I reported was slightly different at the time: Go binaries crash on
hardened kernels that enforce W^X memory pages, because the runtime needs W+X. Normally,
you can disable that enforcement per-binary with tools that tag the ELF with flags, but
those tools crash because of ELF malformations.
Anyway, you're correct that it's a separate, but related bug. I'll open a new issue and
assign it to myself for further poking.
Activity
rsc commentedon Nov 1, 2010
Comment 2:
Owner changed to r...@golang.org.
Status changed to LongTerm.
gopherbot commentedon Feb 1, 2011
Comment 3 by mhantsch:
strip actually emits a bunch of warnings: max@mahako:~/src/test$ cat hello.go package main func main() { print("Hello world.\n") } max@mahako:~/src/test$ 8g hello.go max@mahako:~/src/test$ 8l -o hello hello.8 max@mahako:~/src/test$ ./hello Hello world. max@mahako:~/src/test$ strip hello BFD: stGWSejb: section .rodata vma 0x8054000 overlaps previous sections BFD: stGWSejb: section .plt vma 0x8054010 overlaps previous sections BFD: stGWSejb: section .hash vma 0x8054020 overlaps previous sections BFD: stGWSejb: section .dynstr vma 0x8054034 overlaps previous sections BFD: stGWSejb: section .dynamic vma 0x8054050 overlaps previous sections BFD: stGWSejb: section .gopclntab vma 0x80581a8 overlaps previous sections BFD: stGWSejb: section .gosymtab vma 0x8059b68 overlaps previous sections BFD: stGWSejb: section .got.plt vma 0x8069040 overlaps previous sections BFD: stGWSejb: section .bss vma 0x806a3b8 overlaps previous sections BFD: stGWSejb: warning: allocated section `.interp' not in segment max@mahako:~/src/test$ ./hello Segmentation faultgopherbot commentedon Feb 1, 2011
Comment 4 by slairf:
rsc commentedon Feb 1, 2011
Comment 5:
rsc commentedon Feb 2, 2011
Comment 6:
Issue #1280 has been merged into this issue.
alberts commentedon Feb 15, 2011
Comment 7:
gopherbot commentedon Feb 15, 2011
Comment 8 by slairf:
Comment 7: I don't think that elfutils is a safe way to determine whether an ELF Binary is "wellformed". Consider this C Code: #include <stdio.h> int main() { printf("Hello World\n"); return 0; } Now, after running elflint: section [10] '.rel.plt': relocation 0: offset out of bounds section [10] '.rel.plt': relocation 1: offset out of bounds section [10] '.rel.plt': relocation 2: offset out of bounds section [27] '.symtab': _GLOBAL_OFFSET_TABLE_ symbol size 0 does not match .got.plt section size 24 section [27] '.symtab': _DYNAMIC symbol size 0 does not match dynamic segment size 200 And now, the same with Go: package main import "fmt" func main() { fmt.Printf("Hello world\n") } And elflint: PHDR segment not contained in a loaded segment section [ 1] '.interp': alloc flag set but section not in any loaded segment section [12] '.rodata' has wrong flags: expected ALLOC and possibly MERGE|STRINGS, is WRITE|ALLOC I suppose that elflint actually has a hardcoded pattern for ELF Binaries, or some such...rsc commentedon Mar 4, 2011
Comment 9:
Issue #1578 has been merged into this issue.
rsc commentedon Mar 6, 2011
Comment 10:
Issue #1580 has been merged into this issue.
gopherbot commentedon Mar 16, 2011
Comment 11 by majava3000:
I wrote a small program (in python, sry) that will run readelf -S and sort the results so that the issues might be more visible. It prints out zero sized sections too, but feel free ignore those. On tutorial hello world, with 6g pulled in 2011-03-16, the results are as follows (prior to even running strip): ./parse-sections.py 6.out SectName VMAddress Size(B) Errors .interp 0x00400be4 28 .text 0x00400c00 237618 .rela.plt 0x0043b000 0 ZERO SIZED SECTION .rela 0x0043b000 0 OVERLAPS WITH PREVIOUS, ZERO SIZED SECTION .dynstr 0x0043b000 4 OVERLAPS WITH PREVIOUS .rodata 0x0043b000 788232 OVERLAPS WITH PREVIOUS .plt 0x0043b004 16 OVERLAPS WITH PREVIOUS .hash 0x0043b014 20 .dynsym 0x0043b028 24 .dynamic 0x0043b040 224 .shstrtab 0x0043b120 340 .gopclntab 0x0048f9a8 21080 .gosymtab 0x00494c00 420616 .got 0x004fc000 0 ZERO SIZED SECTION .data 0x004fc000 8160 OVERLAPS WITH PREVIOUS .got.plt 0x004fc118 24 OVERLAPS WITH PREVIOUS .bss 0x004fdfe0 33647768 Some of the overlaps are quite serious in range. These will certainly trigger the warnings of libbfd (that strip uses). The silly little python script I wrote can be found at http://iohazard.net/pub/go/parse-sections.py .niemeyer commentedon Jun 14, 2011
Comment 12:
rsc commentedon Jun 14, 2011
Comment 13:
niemeyer commentedon Jun 14, 2011
Comment 14:
Owner changed to @niemeyer.
Status changed to Started.
niemeyer commentedon Jun 28, 2011
Comment 15:
This issue was closed by revision cf143e9.
Status changed to Fixed.
gopherbot commentedon Jun 30, 2011
Comment 16 by slairf:
niemeyer commentedon Jun 30, 2011
Comment 17:
gopherbot commentedon Jun 30, 2011
Comment 18 by slairf:
rsc commentedon Jun 30, 2011
Comment 19:
Status changed to Accepted.
gopherbot commentedon Jun 30, 2011
Comment 20 by danderson@google.com:
niemeyer commentedon Jun 30, 2011
Comment 21:
gopherbot commentedon Jun 30, 2011
Comment 22 by danderson@google.com:
niemeyer commentedon Jun 30, 2011
Comment 23:
gopherbot commentedon Jun 30, 2011
Comment 24 by danderson@google.com:
niemeyer commentedon Jul 20, 2011
Comment 25:
This issue was closed by revision ba2e3af.
Status changed to Fixed.