aboutsummaryrefslogtreecommitdiff
path: root/src/debug/dwarf/entry_test.go
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2016-03-16 14:15:54 -0700
committerIan Lance Taylor <iant@golang.org>2016-03-22 14:06:09 +0000
commitd1b8871f13203cd99d5e7d686170f0e266760084 (patch)
tree7458f93ff93d8c7b849eab786932a1682657337b /src/debug/dwarf/entry_test.go
parent77f4b773e72b0840a1ce0b314cba44dff9fbaf31 (diff)
downloadgo-d1b8871f13203cd99d5e7d686170f0e266760084.tar.xz
debug/dwarf: add Reader.SeekPC and Data.Ranges
These new methods help find the compilation unit to pass to the LineReader method in order to find the line information for a PC. The Ranges method also helps identify the specific function for a PC, needed to determine the function name. This uses the .debug.ranges section if necessary, and changes the object file format packages to pass in the section contents if available. Change-Id: I5ebc3d27faaf1a126ffb17a1e6027efdf64af836 Reviewed-on: https://go-review.googlesource.com/20769 Reviewed-by: Austin Clements <austin@google.com> Run-TryBot: Ian Lance Taylor <iant@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
Diffstat (limited to 'src/debug/dwarf/entry_test.go')
-rw-r--r--src/debug/dwarf/entry_test.go101
1 files changed, 101 insertions, 0 deletions
diff --git a/src/debug/dwarf/entry_test.go b/src/debug/dwarf/entry_test.go
index 8bd2d2a8ad..58a5d570be 100644
--- a/src/debug/dwarf/entry_test.go
+++ b/src/debug/dwarf/entry_test.go
@@ -6,6 +6,7 @@ package dwarf_test
import (
. "debug/dwarf"
+ "reflect"
"testing"
)
@@ -34,3 +35,103 @@ func TestSplit(t *testing.T) {
t.Fatalf("bad class: have %s, want %s", f.Class, ClassUnknown)
}
}
+
+// wantRange maps from a PC to the ranges of the compilation unit
+// containing that PC.
+type wantRange struct {
+ pc uint64
+ ranges [][2]uint64
+}
+
+func TestReaderSeek(t *testing.T) {
+ want := []wantRange{
+ {0x40059d, [][2]uint64{{0x40059d, 0x400601}}},
+ {0x400600, [][2]uint64{{0x40059d, 0x400601}}},
+ {0x400601, [][2]uint64{{0x400601, 0x400611}}},
+ {0x4005f0, [][2]uint64{{0x40059d, 0x400601}}}, // loop test
+ {0x10, nil},
+ {0x400611, nil},
+ }
+ testRanges(t, "testdata/line-gcc.elf", want)
+}
+
+func TestRangesSection(t *testing.T) {
+ want := []wantRange{
+ {0x400500, [][2]uint64{{0x400500, 0x400549}, {0x400400, 0x400408}}},
+ {0x400400, [][2]uint64{{0x400500, 0x400549}, {0x400400, 0x400408}}},
+ {0x400548, [][2]uint64{{0x400500, 0x400549}, {0x400400, 0x400408}}},
+ {0x400407, [][2]uint64{{0x400500, 0x400549}, {0x400400, 0x400408}}},
+ {0x400408, nil},
+ {0x400449, nil},
+ {0x4003ff, nil},
+ }
+ testRanges(t, "testdata/ranges.elf", want)
+}
+
+func testRanges(t *testing.T, name string, want []wantRange) {
+ d := elfData(t, name)
+ r := d.Reader()
+ for _, w := range want {
+ entry, err := r.SeekPC(w.pc)
+ if err != nil {
+ if w.ranges != nil {
+ t.Errorf("%s: missing Entry for %#x", name, w.pc)
+ }
+ if err != ErrUnknownPC {
+ t.Errorf("%s: expected ErrUnknownPC for %#x, got %v", name, w.pc, err)
+ }
+ continue
+ }
+
+ ranges, err := d.Ranges(entry)
+ if err != nil {
+ t.Errorf("%s: %v", name, err)
+ continue
+ }
+ if !reflect.DeepEqual(ranges, w.ranges) {
+ t.Errorf("%s: for %#x got %x, expected %x", name, w.pc, ranges, w.ranges)
+ }
+ }
+}
+
+func TestReaderRanges(t *testing.T) {
+ d := elfData(t, "testdata/line-gcc.elf")
+
+ subprograms := []struct {
+ name string
+ ranges [][2]uint64
+ }{
+ {"f1", [][2]uint64{{0x40059d, 0x4005e7}}},
+ {"main", [][2]uint64{{0x4005e7, 0x400601}}},
+ {"f2", [][2]uint64{{0x400601, 0x400611}}},
+ }
+
+ r := d.Reader()
+ i := 0
+ for entry, err := r.Next(); entry != nil && err == nil; entry, err = r.Next() {
+ if entry.Tag != TagSubprogram {
+ continue
+ }
+
+ if i > len(subprograms) {
+ t.Fatalf("too many subprograms (expected at most %d)", i)
+ }
+
+ if got := entry.Val(AttrName).(string); got != subprograms[i].name {
+ t.Errorf("subprogram %d name is %s, expected %s", i, got, subprograms[i].name)
+ }
+ ranges, err := d.Ranges(entry)
+ if err != nil {
+ t.Errorf("subprogram %d: %v", i, err)
+ continue
+ }
+ if !reflect.DeepEqual(ranges, subprograms[i].ranges) {
+ t.Errorf("subprogram %d ranges are %x, expected %x", i, ranges, subprograms[i].ranges)
+ }
+ i++
+ }
+
+ if i < len(subprograms) {
+ t.Errorf("saw only %d subprograms, expected %d", i, len(subprograms))
+ }
+}