110 lines
1.9 KiB
Go
110 lines
1.9 KiB
Go
package frame
|
|
|
|
import (
|
|
"debug/elf"
|
|
"debug/gosym"
|
|
"io/ioutil"
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
)
|
|
|
|
func gosymData(testfile string, t testing.TB) *gosym.Table {
|
|
f, err := os.Open(testfile)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
e, err := elf.NewFile(f)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
return parseGoSym(t, e)
|
|
}
|
|
|
|
func grabDebugFrameSection(fp string, t testing.TB) []byte {
|
|
p, err := filepath.Abs(fp)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
f, err := os.Open(p)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
ef, err := elf.NewFile(f)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
data, err := ef.Section(".debug_frame").Data()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
return data
|
|
}
|
|
|
|
func parseGoSym(t testing.TB, exe *elf.File) *gosym.Table {
|
|
symdat, err := exe.Section(".gosymtab").Data()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
pclndat, err := exe.Section(".gopclntab").Data()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
pcln := gosym.NewLineTable(pclndat, exe.Section(".text").Addr)
|
|
tab, err := gosym.NewTable(symdat, pcln)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
return tab
|
|
}
|
|
|
|
func TestFDEForPC(t *testing.T) {
|
|
fde1 := &FrameDescriptionEntry{AddressRange: &addrange{begin: 100, end: 200}}
|
|
fde2 := &FrameDescriptionEntry{AddressRange: &addrange{begin: 50, end: 99}}
|
|
fde3 := &FrameDescriptionEntry{AddressRange: &addrange{begin: 0, end: 49}}
|
|
fde4 := &FrameDescriptionEntry{AddressRange: &addrange{begin: 201, end: 245}}
|
|
|
|
tree := NewFrameIndex()
|
|
tree.Put(fde1)
|
|
tree.Put(fde2)
|
|
tree.Put(fde3)
|
|
tree.Put(fde4)
|
|
|
|
node, ok := tree.Find(Addr(35))
|
|
if !ok {
|
|
t.Fatal("Could not find FDE")
|
|
}
|
|
|
|
if node != fde3 {
|
|
t.Fatal("Got incorrect fde")
|
|
}
|
|
}
|
|
|
|
func BenchmarkFDEForPC(b *testing.B) {
|
|
f, err := os.Open("testdata/frame")
|
|
if err != nil {
|
|
b.Fatal(err)
|
|
}
|
|
defer f.Close()
|
|
|
|
data, err := ioutil.ReadAll(f)
|
|
if err != nil {
|
|
b.Fatal(err)
|
|
}
|
|
fdes := Parse(data)
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
// bench worst case, exhaustive search
|
|
_, _ = fdes.FDEForPC(0x455555555)
|
|
}
|
|
}
|