debug/elf, debug/dwarf: DWARF line number fixes.
authorian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 6 Sep 2012 05:28:02 +0000 (05:28 +0000)
committerian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 6 Sep 2012 05:28:02 +0000 (05:28 +0000)
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
libgo/go/debug/elf/file.go

index f3456fb..3ab2f2b 100644 (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) {
index c2c03d2..31895f1 100644 (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.