diff --git a/src/debug/dwarf/open.go b/src/debug/dwarf/open.go index 0e9c01c2e9..ba51d2b22e 100644 --- a/src/debug/dwarf/open.go +++ b/src/debug/dwarf/open.go @@ -58,7 +58,14 @@ func New(abbrev, aranges, frame, info, line, pubnames, ranges, str []byte) (*Dat if len(d.info) < 6 { return nil, DecodeError{"info", Offset(len(d.info)), "too short"} } + // 32-bit dwarf has 4 byte size then 2 byte version x, y := d.info[4], d.info[5] + if d.info[0] == 255 && d.info[1] == 255 { + // 64-bit DWARF has 4 bytes of FF, then 8 byte size, + // then 2 byte version + x = d.info[12] + y = d.info[13] + } switch { case x == 0 && y == 0: return nil, DecodeError{"info", 4, "unsupported version 0"} diff --git a/src/debug/dwarf/unit.go b/src/debug/dwarf/unit.go index e45aed7ad1..f7c0e816db 100644 --- a/src/debug/dwarf/unit.go +++ b/src/debug/dwarf/unit.go @@ -62,12 +62,24 @@ func (d *Data) parseUnits() ([]unit, error) { var n Offset n, u.is64 = b.unitLength() vers := b.uint16() + // Count the bytes of header read, not counting size + var hbcount uint + hbcount = 2 // Not counting size if vers != 2 && vers != 3 && vers != 4 { b.error("unsupported DWARF version " + strconv.Itoa(int(vers))) break } u.vers = int(vers) - atable, err := d.parseAbbrev(b.uint32(), u.vers) + var aoff uint32 + if !u.is64 { + aoff = b.uint32() + hbcount += 4 + } else { + // For now, ignore the high bits + aoff = uint32(b.uint64()) + hbcount += 8 + } + atable, err := d.parseAbbrev(aoff, u.vers) if err != nil { if b.err == nil { b.err = err @@ -76,8 +88,9 @@ func (d *Data) parseUnits() ([]unit, error) { } u.atable = atable u.asize = int(b.uint8()) + hbcount += 1 u.off = b.off - u.data = b.bytes(int(n - (2 + 4 + 1))) + u.data = b.bytes(int(n - Offset(hbcount))) } if b.err != nil { return nil, b.err