aboutsummaryrefslogtreecommitdiff
path: root/libgo
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2012-09-06 05:28:02 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2012-09-06 05:28:02 +0000
commita85cfff41dad8c074b624c6249ae7c2655033dca (patch)
tree75972449d1a56174c95af8afe2c4daf206a4aeab /libgo
parent67401072c23a76f3a6926e93d117a7281cb6269d (diff)
downloadgcc-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.go50
-rw-r--r--libgo/go/debug/elf/file.go6
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.