aboutsummaryrefslogtreecommitdiff
path: root/src/debug/dwarf
diff options
context:
space:
mode:
authorAustin Clements <austin@google.com>2015-03-05 15:07:00 -0500
committerAustin Clements <austin@google.com>2015-03-11 21:35:21 +0000
commit9dfbcd8facae22e2be8bc527e1877b1e23812073 (patch)
treee5c8d2c9bf218828bd1a55db0360d1b6d0845cba /src/debug/dwarf
parentd533e3955db945072ab2dfcca1cab57099569260 (diff)
downloadgo-9dfbcd8facae22e2be8bc527e1877b1e23812073.tar.xz
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 <nigeltao@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org>
Diffstat (limited to 'src/debug/dwarf')
-rw-r--r--src/debug/dwarf/buf.go11
-rw-r--r--src/debug/dwarf/line.go9
-rw-r--r--src/debug/dwarf/typeunit.go16
-rw-r--r--src/debug/dwarf/unit.go19
4 files changed, 23 insertions, 32 deletions
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)))