Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

Already on GitHub? Sign in to your account

ld: ELF binaries not compatible with strip #1242

Closed
gopherbot opened this Issue Nov 1, 2010 · 24 comments

Comments

Projects
None yet
4 participants

by slairf:

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
Contributor

rsc commented Nov 1, 2010

Comment 2:

Owner changed to r...@golang.org.

Status changed to LongTerm.

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 fault

Comment 4 by slairf:

> strip actually emits a bunch of warnings:
I get similar warnings:
$ strip ./main
BFD: ./stkhBl0d: section .rodata lma 0x807e000 adjusted to 0x807e010
BFD: ./stkhBl0d: section .plt lma 0x807e010 adjusted to 0x8119fb8
BFD: ./stkhBl0d: section .hash lma 0x807e020 adjusted to 0x8119fc8
BFD: ./stkhBl0d: section .dynstr lma 0x807e034 adjusted to 0x8119fdc
BFD: ./stkhBl0d: section .dynamic lma 0x807e064 adjusted to 0x811a00c
BFD: ./stkhBl0d: section .gopclntab lma 0x80b29ec adjusted to 0x811a084
BFD: ./stkhBl0d: section .gosymtab lma 0x80b78c0 adjusted to 0x811ef58
BFD: ./stkhBl0d: section .got.plt lma 0x811a098 adjusted to 0x811ba58
BFD: ./stkhBl0d: section .bss lma 0x811ba58 adjusted to 0x811ba64
BFD: ./stkhBl0d: warning: allocated section `.interp' not in segment
Contributor

rsc commented Feb 1, 2011

Comment 5:

Yes, the problems are known.
Patches welcome.
Contributor

rsc commented Feb 2, 2011

Comment 6:

Issue #1280 has been merged into this issue.

Contributor

alberts commented Feb 15, 2011

Comment 7:

elfutils has a useful tool called eu-elflint.
eu-elflint $GOROOT/bin/6g
eu-elflint $GOROOT/bin/cgo

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...
Contributor

rsc commented Mar 4, 2011

Comment 9:

Issue #1578 has been merged into this issue.

Contributor

rsc commented Mar 6, 2011

Comment 10:

Issue #1580 has been merged into this issue.

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 .
Contributor

niemeyer commented Jun 14, 2011

Comment 12:

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.
Contributor

rsc commented Jun 14, 2011

Comment 13:

This one is likely not very hard.  Patches welcome.  :-)
Contributor

niemeyer commented Jun 14, 2011

Comment 14:

Ok, I'll send a couple of initial minors from last night for appraisal.

Owner changed to @niemeyer.

Status changed to Started.

Contributor

niemeyer commented Jun 28, 2011

Comment 15:

This issue was closed by revision cf143e9.

Status changed to Fixed.

Comment 16 by slairf:

> This issue was closed by revision 2efa68a4183d.
Huh? I just updated my local clone, and the bug still persists...
Contributor

niemeyer commented Jun 30, 2011

Comment 17:

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

Comment 18 by slairf:

Okay, but this bug should reflagged anyway, as "Fixed" would be misleading
Contributor

rsc commented Jun 30, 2011

Comment 19:

Status changed to Accepted.

Comment 20 by danderson@google.com:

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.
Contributor

niemeyer commented Jun 30, 2011

Comment 21:

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.

Comment 22 by danderson@google.com:

I did open another one, a long time ago. It was closed as a duplicate of this one.
Contributor

niemeyer commented Jun 30, 2011

Comment 23:

Which number?  I can't find it.
I believe it should be reopened.  strip works by removing the overlaps.

Comment 24 by danderson@google.com:

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.
Contributor

niemeyer commented Jul 20, 2011

Comment 25:

This issue was closed by revision ba2e3af.

Status changed to Fixed.

@gopherbot gopherbot locked and limited conversation to collaborators Jun 24, 2016

This issue was closed.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.