pkg/proc: improve stripped binary support with PIE (#3421)
Take into account static base for PIE binaries.
This commit is contained in:
parent
14d9c1881d
commit
656c4f13df
@ -609,15 +609,15 @@ func (fn *Function) AllPCs(excludeFile string, excludeLine int) ([]uint64, error
|
||||
return fn.cu.lineInfo.AllPCsBetween(fn.Entry, fn.End-1, excludeFile, excludeLine)
|
||||
}
|
||||
var pcs []uint64
|
||||
fnFile, lastLine, _ := fn.cu.image.symTable.PCToLine(fn.Entry)
|
||||
for pc := fn.Entry; pc < fn.End; pc++ {
|
||||
fnFile, lastLine, _ := fn.cu.image.symTable.PCToLine(fn.Entry - fn.cu.image.StaticBase)
|
||||
for pc := fn.Entry - fn.cu.image.StaticBase; pc < fn.End-fn.cu.image.StaticBase; pc++ {
|
||||
f, line, pcfn := fn.cu.image.symTable.PCToLine(pc)
|
||||
if pcfn == nil {
|
||||
continue
|
||||
}
|
||||
if f == fnFile && line > lastLine {
|
||||
lastLine = line
|
||||
pcs = append(pcs, pc)
|
||||
pcs = append(pcs, pc+fn.cu.image.StaticBase)
|
||||
}
|
||||
}
|
||||
return pcs, nil
|
||||
@ -762,7 +762,7 @@ func (bi *BinaryInfo) EntryLineForFunc(fn *Function) (string, int) {
|
||||
|
||||
func (bi *BinaryInfo) pcToLine(fn *Function, pc uint64) (string, int) {
|
||||
if fn.cu.lineInfo == nil {
|
||||
f, l, _ := fn.cu.image.symTable.PCToLine(pc)
|
||||
f, l, _ := fn.cu.image.symTable.PCToLine(pc - fn.cu.image.StaticBase)
|
||||
return f, l
|
||||
}
|
||||
f, l := fn.cu.lineInfo.PCToLine(fn.Entry, pc)
|
||||
@ -1461,7 +1461,7 @@ func loadBinaryInfoElf(bi *BinaryInfo, image *Image, path string, addr uint64, w
|
||||
for _, f := range image.symTable.Funcs {
|
||||
cu := &compileUnit{}
|
||||
cu.image = image
|
||||
fn := Function{Name: f.Name, Entry: f.Entry, End: f.End, cu: cu}
|
||||
fn := Function{Name: f.Name, Entry: f.Entry + image.StaticBase, End: f.End + image.StaticBase, cu: cu}
|
||||
bi.Functions = append(bi.Functions, fn)
|
||||
}
|
||||
for f := range image.symTable.Files {
|
||||
|
||||
@ -1,40 +1,11 @@
|
||||
package proc
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"debug/buildinfo"
|
||||
"debug/elf"
|
||||
"debug/gosym"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// From go/src/debug/gosym/pclntab.go
|
||||
const (
|
||||
go12magic = 0xfffffffb
|
||||
go116magic = 0xfffffffa
|
||||
go118magic = 0xfffffff0
|
||||
go120magic = 0xfffffff1
|
||||
)
|
||||
|
||||
// Select the magic number based on the Go version
|
||||
func magicNumber(goVersion string) []byte {
|
||||
bs := make([]byte, 4)
|
||||
var magic uint32
|
||||
if strings.Compare(goVersion, "go1.20") >= 0 {
|
||||
magic = go120magic
|
||||
} else if strings.Compare(goVersion, "go1.18") >= 0 {
|
||||
magic = go118magic
|
||||
} else if strings.Compare(goVersion, "go1.16") >= 0 {
|
||||
magic = go116magic
|
||||
} else {
|
||||
magic = go12magic
|
||||
}
|
||||
binary.LittleEndian.PutUint32(bs, magic)
|
||||
return bs
|
||||
}
|
||||
|
||||
func readPcLnTableElf(exe *elf.File, path string) (*gosym.Table, error) {
|
||||
// Default section label is .gopclntab
|
||||
sectionLabel := ".gopclntab"
|
||||
@ -42,7 +13,7 @@ func readPcLnTableElf(exe *elf.File, path string) (*gosym.Table, error) {
|
||||
section := exe.Section(sectionLabel)
|
||||
if section == nil {
|
||||
// binary may be built with -pie
|
||||
sectionLabel = ".data.rel.ro"
|
||||
sectionLabel = ".data.rel.ro.gopclntab"
|
||||
section = exe.Section(sectionLabel)
|
||||
if section == nil {
|
||||
return nil, fmt.Errorf("could not read section .gopclntab")
|
||||
@ -53,17 +24,6 @@ func readPcLnTableElf(exe *elf.File, path string) (*gosym.Table, error) {
|
||||
return nil, fmt.Errorf("found section but could not read .gopclntab")
|
||||
}
|
||||
|
||||
bi, err := buildinfo.ReadFile(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Find .gopclntab by magic number even if there is no section label
|
||||
magic := magicNumber(bi.GoVersion)
|
||||
pclntabIndex := bytes.Index(tableData, magic)
|
||||
if pclntabIndex >= 0 {
|
||||
tableData = tableData[pclntabIndex:]
|
||||
}
|
||||
addr := exe.Section(".text").Addr
|
||||
lineTable := gosym.NewLineTable(tableData, addr)
|
||||
symTable, err := gosym.NewTable([]byte{}, lineTable)
|
||||
|
||||
@ -3169,7 +3169,6 @@ func TestDebugStripped(t *testing.T) {
|
||||
// Currently only implemented for Linux ELF executables.
|
||||
// TODO(derekparker): Add support for Mach-O and PE.
|
||||
skipUnlessOn(t, "linux only", "linux")
|
||||
skipOn(t, "does not work with PIE", "pie")
|
||||
withTestProcessArgs("testnextprog", t, "", []string{}, protest.LinkStrip, func(p *proc.Target, grp *proc.TargetGroup, f protest.Fixture) {
|
||||
setFunctionBreakpoint(p, t, "main.main")
|
||||
assertNoError(grp.Continue(), t, "Continue")
|
||||
|
||||
Loading…
Reference in New Issue
Block a user