From 059806e2c8d114318e3a650050de54feabb9af55 Mon Sep 17 00:00:00 2001 From: Chris Quenelle Date: Tue, 18 Jul 2017 18:29:11 -0700 Subject: [PATCH 1/2] Fix a few dwarf64 parsing problems. Nothing fancy. This fixes bugs that show up when dwarf from Studio compilers gets mixed in via crt files. --- src/debug/dwarf/open.go | 7 +++++++ src/debug/dwarf/unit.go | 16 ++++++++++++++-- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/debug/dwarf/open.go b/src/debug/dwarf/open.go index 0e9c01c2e9..ba3819700a 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..97f5f1f72f 100644 --- a/src/debug/dwarf/unit.go +++ b/src/debug/dwarf/unit.go @@ -62,12 +62,23 @@ func (d *Data) parseUnits() ([]unit, error) { var n Offset n, u.is64 = b.unitLength() vers := b.uint16() + var header_bytes_read uint + header_bytes_read = 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() + header_bytes_read += 4 + } else { + // For now ignore the high bits + aoff = uint32(b.uint64()) + header_bytes_read += 8 + } + atable, err := d.parseAbbrev(aoff, u.vers) if err != nil { if b.err == nil { b.err = err @@ -76,8 +87,9 @@ func (d *Data) parseUnits() ([]unit, error) { } u.atable = atable u.asize = int(b.uint8()) + header_bytes_read += 1 u.off = b.off - u.data = b.bytes(int(n - (2 + 4 + 1))) + u.data = b.bytes(int(n - Offset(header_bytes_read))) } if b.err != nil { return nil, b.err From 9c4c1b232ef442194c8f2b58a6a6f10bba9bdd11 Mon Sep 17 00:00:00 2001 From: Chris Quenelle Date: Fri, 21 Jul 2017 12:55:11 -0700 Subject: [PATCH 2/2] Fix a few dwarf64 parsing problems. This fixes bugs that show up when dwarf from Studio compilers gets mixed in via crt files. --- src/debug/dwarf/open.go | 14 +++++++------- src/debug/dwarf/unit.go | 15 ++++++++------- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/src/debug/dwarf/open.go b/src/debug/dwarf/open.go index ba3819700a..ba51d2b22e 100644 --- a/src/debug/dwarf/open.go +++ b/src/debug/dwarf/open.go @@ -58,14 +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 + // 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] - } + 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 97f5f1f72f..f7c0e816db 100644 --- a/src/debug/dwarf/unit.go +++ b/src/debug/dwarf/unit.go @@ -62,8 +62,9 @@ func (d *Data) parseUnits() ([]unit, error) { var n Offset n, u.is64 = b.unitLength() vers := b.uint16() - var header_bytes_read uint - header_bytes_read = 2 // Not counting size + // 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 @@ -72,11 +73,11 @@ func (d *Data) parseUnits() ([]unit, error) { var aoff uint32 if !u.is64 { aoff = b.uint32() - header_bytes_read += 4 + hbcount += 4 } else { - // For now ignore the high bits + // For now, ignore the high bits aoff = uint32(b.uint64()) - header_bytes_read += 8 + hbcount += 8 } atable, err := d.parseAbbrev(aoff, u.vers) if err != nil { @@ -87,9 +88,9 @@ func (d *Data) parseUnits() ([]unit, error) { } u.atable = atable u.asize = int(b.uint8()) - header_bytes_read += 1 + hbcount += 1 u.off = b.off - u.data = b.bytes(int(n - Offset(header_bytes_read))) + u.data = b.bytes(int(n - Offset(hbcount))) } if b.err != nil { return nil, b.err