// the "mac" section.
ClassMacPtr
- // ClassMacPtr represents values that are an int64 offset into
+ // ClassRangeListPtr represents values that are an int64 offset into
// the "rangelist" section.
ClassRangeListPtr
// into the "loclists" section.
ClassLocList
- // ClassRngList represents values that are an int64 offset
+ // ClassRngList represents values that are a uint64 offset
// from the base of the "rnglists" section.
ClassRngList
return val
}
+ resolveRnglistx := func(rnglistsBase, off uint64) uint64 {
+ is64, _ := b.format.dwarf64()
+ if is64 {
+ off *= 8
+ } else {
+ off *= 4
+ }
+ off += rnglistsBase
+ if uint64(int(off)) != off {
+ b.error("DW_FORM_rnglistx offset out of range")
+ }
+
+ b1 := makeBuf(b.dwarf, b.format, "rnglists", 0, b.dwarf.rngLists)
+ b1.skip(int(off))
+ if is64 {
+ off = b1.uint64()
+ } else {
+ off = uint64(b1.uint32())
+ }
+ if b1.err != nil {
+ b.err = b1.err
+ return 0
+ }
+ if uint64(int(off)) != off {
+ b.error("DW_FORM_rnglistx indirect offset out of range")
+ }
+ return rnglistsBase + off
+ }
+
for i := range e.Field {
e.Field[i].Attr = a.field[i].attr
e.Field[i].Class = a.field[i].class
// rnglist
case formRnglistx:
- val = b.uint()
+ off := b.uint()
+
+ // We have to adjust by the rnglists_base of
+ // the compilation unit. This won't work if
+ // the program uses Reader.Seek to skip over
+ // the unit. Not much we can do about that.
+ var rnglistsBase int64
+ if cu != nil {
+ rnglistsBase, _ = cu.Val(AttrRnglistsBase).(int64)
+ } else if a.tag == TagCompileUnit {
+ delay = append(delay, delayed{i, off, formRnglistx})
+ break
+ }
+
+ val = resolveRnglistx(uint64(rnglistsBase), off)
}
e.Field[i].Val = val
if b.err != nil {
return nil
}
+ case formRnglistx:
+ rnglistsBase, _ := e.Val(AttrRnglistsBase).(int64)
+ e.Field[del.idx].Val = resolveRnglistx(uint64(rnglistsBase), del.off)
+ if b.err != nil {
+ return nil
+ }
}
}
return d.dwarf5Ranges(u, cu, base, ranges, ret)
case ClassRngList:
- // TODO: support DW_FORM_rnglistx
- return ret, nil
+ rnglist, ok := field.Val.(uint64)
+ if !ok {
+ return ret, nil
+ }
+ cu, base, err := d.baseAddressForEntry(e)
+ if err != nil {
+ return nil, err
+ }
+ return d.dwarf5Ranges(u, cu, base, int64(rnglist), ret)
default:
return ret, nil
testRanges(t, "testdata/ranges.elf", want)
}
+func TestRangesRnglistx(t *testing.T) {
+ want := []wantRange{
+ {0x401000, [][2]uint64{{0x401020, 0x40102c}, {0x401000, 0x40101d}}},
+ {0x40101c, [][2]uint64{{0x401020, 0x40102c}, {0x401000, 0x40101d}}},
+ {0x40101d, nil},
+ {0x40101f, nil},
+ {0x401020, [][2]uint64{{0x401020, 0x40102c}, {0x401000, 0x40101d}}},
+ {0x40102b, [][2]uint64{{0x401020, 0x40102c}, {0x401000, 0x40101d}}},
+ {0x40102c, nil},
+ }
+ testRanges(t, "testdata/rnglistx.elf", want)
+}
+
func testRanges(t *testing.T, name string, want []wantRange) {
d := elfData(t, name)
r := d.Reader()
testLineTable(t, want, files, elfData(t, "testdata/line-clang.elf"))
}
+func TestLineRnglists(t *testing.T) {
+ // Test a newer file, generated by clang.
+ file := &LineFile{Name: "/usr/local/google/home/iant/foo.c"}
+ want := []LineEntry{
+ {Address: 0x401020, File: file, Line: 12, IsStmt: true},
+ {Address: 0x401020, File: file, Line: 13, Column: 12, IsStmt: true, PrologueEnd: true},
+ {Address: 0x401022, File: file, Line: 13, Column: 7},
+ {Address: 0x401024, File: file, Line: 17, Column: 1, IsStmt: true},
+ {Address: 0x401027, File: file, Line: 16, Column: 10, IsStmt: true},
+ {Address: 0x40102c, EndSequence: true},
+ {Address: 0x401000, File: file, Line: 2, IsStmt: true},
+ {Address: 0x401000, File: file, Line: 6, Column: 17, IsStmt: true, PrologueEnd: true},
+ {Address: 0x401002, File: file, Line: 6, Column: 3},
+ {Address: 0x401019, File: file, Line: 9, Column: 3, IsStmt: true},
+ {Address: 0x40101a, File: file, Line: 0, Column: 3},
+ {Address: 0x40101c, File: file, Line: 9, Column: 3},
+ {Address: 0x40101d, EndSequence: true},
+ }
+ files := [][]*LineFile{{file}}
+
+ testLineTable(t, want, files, elfData(t, "testdata/rnglistx.elf"))
+}
+
func TestLineSeek(t *testing.T) {
d := elfData(t, "testdata/line-gcc.elf")
--- /dev/null
+// clang -gdwarf-5 -O2 -nostdlib
+
+__attribute__((noinline, cold))
+static int sum(int i) {
+ int j, s;
+
+ s = 0;
+ for (j = 0; j < i; j++) {
+ s += j * i;
+ }
+ return s;
+}
+
+int main(int argc, char** argv) {
+ if (argc == 0) {
+ return 0;
+ }
+ return sum(argc);
+}