@@ -67,12 +67,22 @@
switch e.Tag {
case TagCompileUnit, TagSubprogram, TagEntryPoint, TagInlinedSubroutine:
low, lowok := e.Val(AttrLowpc).(uint64)
- high, highok := e.Val(AttrHighpc).(uint64)
+ var high uint64
+ var highok bool
+ switch v := e.Val(AttrHighpc).(type) {
+ case uint64:
+ high = v
+ highok = true
+ case int64:
+ high = low + uint64(v)
+ highok = true
+ }
if lowok && highok {
u.pc = append(u.pc, addrRange{low, high})
- } else if f, ok := e.Val(AttrRanges).(Offset); ok {
- // TODO: Handle AttrRanges and .debug_ranges.
- _ = f
+ } else if off, ok := e.Val(AttrRanges).(Offset); ok {
+ if err := d.readAddressRanges(off, low, u); err != nil {
+ return err
+ }
}
val := e.Val(AttrStmtList)
if val != nil {
@@ -98,6 +108,38 @@
return nil
}
+// readAddressRanges adds address ranges to a unit.
+func (d *Data) readAddressRanges(off Offset, base uint64, u *unit) error {
+ b := makeBuf(d, u, "ranges", off, d.ranges[off:])
+ var highest uint64
+ switch u.addrsize {
+ case 1:
+ highest = 0xff
+ case 2:
+ highest = 0xffff
+ case 4:
+ highest = 0xffffffff
+ case 8:
+ highest = 0xffffffffffffffff
+ default:
+ return errors.New("unknown address size")
+ }
+ for {
+ if b.err != nil {
+ return b.err
+ }
+ low := b.addr()
+ high := b.addr()
+ if low == 0 && high == 0 {
+ return b.err
+ } else if low == highest {
+ base = high
+ } else {
+ u.pc = append(u.pc, addrRange{low + base, high + base})
+ }
+ }
+}
+
// findLine finds the line information for a PC value, given the unit
// containing the information.
func (d *Data) findLine(u *unit, pc uint64) ([]*Line, error) {
@@ -563,7 +563,7 @@
// There are many other DWARF sections, but these
// are the required ones, and the debug/dwarf package
// does not use the others, so don't bother loading them.
- var names = [...]string{"abbrev", "info", "line", "str"}
+ var names = [...]string{"abbrev", "info", "line", "ranges", "str"}
var dat [len(names)][]byte
for i, name := range names {
name = ".debug_" + name
@@ -592,8 +592,8 @@
}
}
- abbrev, info, line, str := dat[0], dat[1], dat[2], dat[3]
- return dwarf.New(abbrev, nil, nil, info, line, nil, nil, str)
+ abbrev, info, line, ranges, str := dat[0], dat[1], dat[2], dat[3], dat[4]
+ return dwarf.New(abbrev, nil, nil, info, line, nil, ranges, str)
}
// Symbols returns the symbol table for f.