debug/elf, debug/dwarf: DWARF line number fixes.

Support DW_AT_high_pc as a constant.
Support DW_AT_ranges.

PR gcc/52583

From-SVN: r191008
This commit is contained in:
Ian Lance Taylor 2012-09-06 05:28:02 +00:00
parent 67401072c2
commit a85cfff41d
2 changed files with 49 additions and 7 deletions

View file

@ -67,12 +67,22 @@ func (d *Data) readUnitLine(i int, u *unit) error {
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 @@ func (d *Data) readUnitLine(i int, u *unit) error {
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) {

View file

@ -563,7 +563,7 @@ func (f *File) DWARF() (*dwarf.Data, error) {
// 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 @@ func (f *File) DWARF() (*dwarf.Data, error) {
}
}
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.