From: Austin Clements Date: Thu, 5 Mar 2015 20:07:00 +0000 (-0500) Subject: debug/dwarf: factor parsing of unit lengths X-Git-Tag: go1.5beta1~1626 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=9dfbcd8facae22e2be8bc527e1877b1e23812073;p=gostls13.git debug/dwarf: factor parsing of unit lengths Many headers in DWARF sections have a "unit length" that can be either 4 bytes or 12 bytes and indicates both the length of the unit and whether the unit is in 32-bit or 64-bit format. Currently, we implement unit length parsing in four different places. Add a "unitLength" method to buf that parses a unit length and use it in these four places. Change-Id: I7950b91caaa92aa5e19aa63debc8ae46178ecc4d Reviewed-on: https://go-review.googlesource.com/7281 Reviewed-by: Nigel Tao Reviewed-by: Ian Lance Taylor --- diff --git a/src/debug/dwarf/buf.go b/src/debug/dwarf/buf.go index 53c46eb4b8..2ade0bd76a 100644 --- a/src/debug/dwarf/buf.go +++ b/src/debug/dwarf/buf.go @@ -163,6 +163,17 @@ func (b *buf) addr() uint64 { return 0 } +func (b *buf) unitLength() (length Offset, dwarf64 bool) { + length = Offset(b.uint32()) + if length == 0xffffffff { + dwarf64 = true + length = Offset(b.uint64()) + } else if length >= 0xfffffff0 { + b.error("unit length has reserved value") + } + return +} + func (b *buf) error(s string) { if b.err == nil { b.data = nil diff --git a/src/debug/dwarf/line.go b/src/debug/dwarf/line.go index 5588c5ca45..ca64bbd7f3 100644 --- a/src/debug/dwarf/line.go +++ b/src/debug/dwarf/line.go @@ -177,14 +177,7 @@ func (r *LineReader) readHeader() error { // Read basic header fields [DWARF2 6.2.4]. hdrOffset := buf.off - dwarf64 := false - unitLength := Offset(buf.uint32()) - if unitLength == 0xffffffff { - dwarf64 = true - unitLength = Offset(buf.uint64()) - } else if unitLength >= 0xfffffff0 { - return DecodeError{"line", hdrOffset, fmt.Sprintf("total length field has reserved value %#x", unitLength)} - } + unitLength, dwarf64 := buf.unitLength() r.endOffset = buf.off + unitLength if r.endOffset > buf.off+Offset(len(buf.data)) { return DecodeError{"line", hdrOffset, fmt.Sprintf("line table end %d exceeds section size %d", r.endOffset, buf.off+Offset(len(buf.data)))} diff --git a/src/debug/dwarf/typeunit.go b/src/debug/dwarf/typeunit.go index 3fd1c9973e..80971bbb90 100644 --- a/src/debug/dwarf/typeunit.go +++ b/src/debug/dwarf/typeunit.go @@ -27,16 +27,10 @@ func (d *Data) parseTypes(name string, types []byte) error { b := makeBuf(d, unknownFormat{}, name, 0, types) for len(b.data) > 0 { base := b.off - dwarf64 := false - n := b.uint32() - if n == 0xffffffff { - n64 := b.uint64() - if n64 != uint64(uint32(n64)) { - b.error("type unit length overflow") - return b.err - } - n = uint32(n64) - dwarf64 = true + n, dwarf64 := b.unitLength() + if n != Offset(uint32(n)) { + b.error("type unit length overflow") + return b.err } hdroff := b.off vers := b.uint16() @@ -79,7 +73,7 @@ func (d *Data) parseTypes(name string, types []byte) error { unit: unit{ base: base, off: boff, - data: b.bytes(int(Offset(n) - (b.off - hdroff))), + data: b.bytes(int(n - (b.off - hdroff))), atable: atable, asize: int(asize), vers: int(vers), diff --git a/src/debug/dwarf/unit.go b/src/debug/dwarf/unit.go index 85c44bbdda..901ba0dabf 100644 --- a/src/debug/dwarf/unit.go +++ b/src/debug/dwarf/unit.go @@ -41,14 +41,10 @@ func (d *Data) parseUnits() ([]unit, error) { nunit := 0 b := makeBuf(d, unknownFormat{}, "info", 0, d.info) for len(b.data) > 0 { - len := b.uint32() - if len == 0xffffffff { - len64 := b.uint64() - if len64 != uint64(uint32(len64)) { - b.error("unit length overflow") - break - } - len = uint32(len64) + len, _ := b.unitLength() + if len != Offset(uint32(len)) { + b.error("unit length overflow") + break } b.skip(int(len)) nunit++ @@ -63,11 +59,8 @@ func (d *Data) parseUnits() ([]unit, error) { for i := range units { u := &units[i] u.base = b.off - n := b.uint32() - if n == 0xffffffff { - u.is64 = true - n = uint32(b.uint64()) - } + var n Offset + n, u.is64 = b.unitLength() vers := b.uint16() if vers != 2 && vers != 3 && vers != 4 { b.error("unsupported DWARF version " + strconv.Itoa(int(vers)))