diff options
Diffstat (limited to 'libgo/go/debug/dwarf/unit.go')
-rw-r--r-- | libgo/go/debug/dwarf/unit.go | 67 |
1 files changed, 35 insertions, 32 deletions
diff --git a/libgo/go/debug/dwarf/unit.go b/libgo/go/debug/dwarf/unit.go index be6093519d5..ceb6cdbff32 100644 --- a/libgo/go/debug/dwarf/unit.go +++ b/libgo/go/debug/dwarf/unit.go @@ -4,23 +4,22 @@ package dwarf -import "strconv" +import ( + "sort" + "strconv" +) // DWARF debug info is split into a sequence of compilation units. // Each unit has its own abbreviation table and address size. type unit struct { - base Offset // byte offset of header within the aggregate info - off Offset // byte offset of data within the aggregate info - lineoff Offset // byte offset of data within the line info - data []byte - atable abbrevTable - asize int - vers int - is64 bool // True for 64-bit DWARF format - dir string - pc []addrRange // PC ranges in this compilation unit - lines []mapLineInfo // PC -> line mapping + base Offset // byte offset of header within the aggregate info + off Offset // byte offset of data within the aggregate info + data []byte + atable abbrevTable + asize int + vers int + is64 bool // True for 64-bit DWARF format } // Implement the dataFormat interface. @@ -37,25 +36,15 @@ func (u *unit) addrsize() int { return u.asize } -// A range is an address range. -type addrRange struct { - low uint64 - high uint64 -} - func (d *Data) parseUnits() ([]unit, error) { // Count units. nunit := 0 b := makeBuf(d, unknownFormat{}, "info", 0, d.info) for len(b.data) > 0 { - len := b.uint32() - if len == 0xffffffff { - len64 := b.uint64() - if len64 != uint64(uint32(len64)) { - b.error("unit length overflow") - break - } - len = uint32(len64) + len, _ := b.unitLength() + if len != Offset(uint32(len)) { + b.error("unit length overflow") + break } b.skip(int(len)) nunit++ @@ -70,18 +59,15 @@ func (d *Data) parseUnits() ([]unit, error) { for i := range units { u := &units[i] u.base = b.off - n := b.uint32() - if n == 0xffffffff { - u.is64 = true - n = uint32(b.uint64()) - } + var n Offset + n, u.is64 = b.unitLength() vers := b.uint16() if vers != 2 && vers != 3 && vers != 4 { b.error("unsupported DWARF version " + strconv.Itoa(int(vers))) break } u.vers = int(vers) - atable, err := d.parseAbbrev(b.uint32()) + atable, err := d.parseAbbrev(b.uint32(), u.vers) if err != nil { if b.err == nil { b.err = err @@ -98,3 +84,20 @@ func (d *Data) parseUnits() ([]unit, error) { } return units, nil } + +// offsetToUnit returns the index of the unit containing offset off. +// It returns -1 if no unit contains this offset. +func (d *Data) offsetToUnit(off Offset) int { + // Find the unit after off + next := sort.Search(len(d.unit), func(i int) bool { + return d.unit[i].off > off + }) + if next == 0 { + return -1 + } + u := &d.unit[next-1] + if u.off <= off && off < u.off+Offset(len(u.data)) { + return next - 1 + } + return -1 +} |