mirror of
https://github.com/golang/go
synced 2024-11-11 18:21:40 -07:00
debug/dwarf: support DW_FORM_rnglistx aka formRnglistx
Change-Id: I7df915978af3488f46a27595a1b04d0d33f81f7b Reviewed-on: https://go-review.googlesource.com/c/go/+/302369 Trust: Ian Lance Taylor <iant@golang.org> Run-TryBot: Ian Lance Taylor <iant@golang.org> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Than McIntosh <thanm@google.com>
This commit is contained in:
parent
63b0a0a5b8
commit
a826f7dc45
@ -317,7 +317,7 @@ const (
|
||||
// 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
|
||||
|
||||
@ -355,7 +355,7 @@ const (
|
||||
// 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
|
||||
|
||||
@ -464,6 +464,35 @@ func (b *buf) entry(cu *Entry, atab abbrevTable, ubase Offset, vers int) *Entry
|
||||
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
|
||||
@ -709,7 +738,21 @@ func (b *buf) entry(cu *Entry, atab abbrevTable, ubase Offset, vers int) *Entry
|
||||
|
||||
// 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
|
||||
@ -734,6 +777,12 @@ func (b *buf) entry(cu *Entry, atab abbrevTable, ubase Offset, vers int) *Entry
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -993,8 +1042,15 @@ func (d *Data) Ranges(e *Entry) ([][2]uint64, error) {
|
||||
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
|
||||
|
@ -84,6 +84,19 @@ func TestRangesSection(t *testing.T) {
|
||||
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()
|
||||
|
@ -117,6 +117,29 @@ func TestLineELFClang(t *testing.T) {
|
||||
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")
|
||||
|
||||
|
19
src/debug/dwarf/testdata/rnglistx.c
vendored
Normal file
19
src/debug/dwarf/testdata/rnglistx.c
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
// 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);
|
||||
}
|
BIN
src/debug/dwarf/testdata/rnglistx.elf
vendored
Executable file
BIN
src/debug/dwarf/testdata/rnglistx.elf
vendored
Executable file
Binary file not shown.
Loading…
Reference in New Issue
Block a user