This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
libgo patch committed: DWARF line reader fixes
- From: Ian Lance Taylor <iant at google dot com>
- To: gcc-patches at gcc dot gnu dot org, gofrontend-dev at googlegroups dot com
- Date: Wed, 05 Sep 2012 22:28:25 -0700
- Subject: libgo patch committed: DWARF line reader fixes
This patch to libgo fixes a couple of things in the DWARF line reader.
It adds support for DW_AT_high_pc as a constant offset from
DW_AT_low_pc. It adds support for DW_AT_ranges. Bootstrapped and ran
Go testsuite on x86_64-unknown-linux-gnu. Committed to mainline and 4.7
branch.
This fixes some testsuite failures reported in PR gcc/52583, although
that PR was originally just for Solaris issues.
Ian
diff -r e4c5f4a31350 libgo/go/debug/dwarf/line.go
--- a/libgo/go/debug/dwarf/line.go Wed Aug 22 21:54:46 2012 -0700
+++ b/libgo/go/debug/dwarf/line.go Wed Sep 05 22:20:02 2012 -0700
@@ -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) {
diff -r e4c5f4a31350 libgo/go/debug/elf/file.go
--- a/libgo/go/debug/elf/file.go Wed Aug 22 21:54:46 2012 -0700
+++ b/libgo/go/debug/elf/file.go Wed Sep 05 22:20:02 2012 -0700
@@ -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.