]> Cypherpunks repositories - gostls13.git/commitdiff
debug/dwarf: factor parsing of unit lengths
authorAustin Clements <austin@google.com>
Thu, 5 Mar 2015 20:07:00 +0000 (15:07 -0500)
committerAustin Clements <austin@google.com>
Wed, 11 Mar 2015 21:35:21 +0000 (21:35 +0000)
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 <nigeltao@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
src/debug/dwarf/buf.go
src/debug/dwarf/line.go
src/debug/dwarf/typeunit.go
src/debug/dwarf/unit.go

index 53c46eb4b818e16be893686d6aeec87f7c266a1c..2ade0bd76ad6eabef752953016a6445205e3762a 100644 (file)
@@ -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
index 5588c5ca451d281e4eb921223ca7dc3323255306..ca64bbd7f3b310778058a3a404d699f5a84e0907 100644 (file)
@@ -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)))}
index 3fd1c9973e54a4dfe6c167f2a769854bc9204326..80971bbb90bb1183d6e12afac79d1f57fce29ad7 100644 (file)
@@ -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),
index 85c44bbddabc79652636b92c779ae5ddba70dec2..901ba0dabf1068da1e3468213222ac9f2f94ce99 100644 (file)
@@ -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)))