diff options
author | Ian Lance Taylor <ian@gcc.gnu.org> | 2012-09-06 05:28:02 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2012-09-06 05:28:02 +0000 |
commit | a85cfff41dad8c074b624c6249ae7c2655033dca (patch) | |
tree | 75972449d1a56174c95af8afe2c4daf206a4aeab /libgo | |
parent | 67401072c23a76f3a6926e93d117a7281cb6269d (diff) | |
download | gcc-a85cfff41dad8c074b624c6249ae7c2655033dca.zip gcc-a85cfff41dad8c074b624c6249ae7c2655033dca.tar.gz gcc-a85cfff41dad8c074b624c6249ae7c2655033dca.tar.bz2 |
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
Diffstat (limited to 'libgo')
-rw-r--r-- | libgo/go/debug/dwarf/line.go | 50 | ||||
-rw-r--r-- | libgo/go/debug/elf/file.go | 6 |
2 files changed, 49 insertions, 7 deletions
diff --git a/libgo/go/debug/dwarf/line.go b/libgo/go/debug/dwarf/line.go index f3456fb..3ab2f2b 100644 --- a/libgo/go/debug/dwarf/line.go +++ b/libgo/go/debug/dwarf/line.go @@ -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) { diff --git a/libgo/go/debug/elf/file.go b/libgo/go/debug/elf/file.go index c2c03d2..31895f1 100644 --- a/libgo/go/debug/elf/file.go +++ b/libgo/go/debug/elf/file.go @@ -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. |