From 1acddee6b765baa91ae1c284a4b07aff659801cb Mon Sep 17 00:00:00 2001 From: ian Date: Thu, 6 Sep 2012 05:28:02 +0000 Subject: [PATCH] debug/elf, debug/dwarf: DWARF line number fixes. Support DW_AT_high_pc as a constant. Support DW_AT_ranges. PR gcc/52583 git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@191008 138bc75d-0d04-0410-961f-82ee72b054a4 --- libgo/go/debug/dwarf/line.go | 50 ++++++++++++++++++++++++++++++++++++++++---- 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. -- 2.7.4