if sect := f.elf.Section(".text"); sect != nil {
textStart = sect.Addr
}
- if sect := f.elf.Section(".gosymtab"); sect != nil {
+
+ sect := f.elf.Section(".gosymtab")
+ if sect == nil {
+ // try .data.rel.ro.gosymtab, for PIE binaries
+ sect = f.elf.Section(".data.rel.ro.gosymtab")
+ }
+ if sect != nil {
if symtab, err = sect.Data(); err != nil {
return 0, nil, nil, err
}
+ } else {
+ // if both sections failed, try the symbol
+ symtab = f.symbolData("runtime.symtab", "runtime.esymtab")
+ }
+
+ sect = f.elf.Section(".gopclntab")
+ if sect == nil {
+ // try .data.rel.ro.gopclntab, for PIE binaries
+ sect = f.elf.Section(".data.rel.ro.gopclntab")
}
- if sect := f.elf.Section(".gopclntab"); sect != nil {
+ if sect != nil {
if pclntab, err = sect.Data(); err != nil {
return 0, nil, nil, err
}
+ } else {
+ // if both sections failed, try the symbol
+ pclntab = f.symbolData("runtime.pclntab", "runtime.epclntab")
}
+
return textStart, symtab, pclntab, nil
}
func (f *elfFile) dwarf() (*dwarf.Data, error) {
return f.elf.DWARF()
}
+
+func (f *elfFile) symbolData(start, end string) []byte {
+ elfSyms, err := f.elf.Symbols()
+ if err != nil {
+ return nil
+ }
+ var addr, eaddr uint64
+ for _, s := range elfSyms {
+ if s.Name == start {
+ addr = s.Value
+ } else if s.Name == end {
+ eaddr = s.Value
+ }
+ if addr != 0 && eaddr != 0 {
+ break
+ }
+ }
+ if addr == 0 || eaddr < addr {
+ return nil
+ }
+ size := eaddr - addr
+ data := make([]byte, size)
+ for _, prog := range f.elf.Progs {
+ if prog.Vaddr <= addr && addr+size-1 <= prog.Vaddr+prog.Filesz-1 {
+ if _, err := prog.ReadAt(data, int64(addr-prog.Vaddr)); err != nil {
+ return nil
+ }
+ return data
+ }
+ }
+ return nil
+}
import (
"cmd/internal/notsha256"
+ "cmd/internal/sys"
"flag"
"fmt"
"go/build"
"RET",
}
+var ppcPIENeed = []string{
+ "BR",
+ "CALL",
+ "RET",
+}
+
var ppcGnuNeed = []string{
"mflr",
"lbz",
case "arm64":
need = append(need, arm64Need...)
case "ppc64", "ppc64le":
- need = append(need, ppcNeed...)
+ var pie bool
+ for _, flag := range flags {
+ if flag == "-buildmode=pie" {
+ pie = true
+ break
+ }
+ }
+ if pie {
+ // In PPC64 PIE binaries we use a "local entry point" which is
+ // function symbol address + 8. Currently we don't symbolize that.
+ // Expect a different output.
+ need = append(need, ppcPIENeed...)
+ } else {
+ need = append(need, ppcNeed...)
+ }
}
if printGnuAsm {
testDisasm(t, "fmthello.go", false, false, "-ldflags=-linkmode=external")
}
+func TestDisasmPIE(t *testing.T) {
+ if !sys.BuildModeSupported("gc", "pie", runtime.GOOS, runtime.GOARCH) {
+ t.Skipf("skipping on %s/%s, PIE buildmode not supported", runtime.GOOS, runtime.GOARCH)
+ }
+ t.Parallel()
+ testDisasm(t, "fmthello.go", false, false, "-buildmode=pie")
+}
+
func TestDisasmGoobj(t *testing.T) {
mustHaveDisasm(t)