From: Austin Clements Date: Wed, 4 Mar 2015 01:53:40 +0000 (-0500) Subject: debug/dwarf: factor finding unit containing entry offset X-Git-Tag: go1.5beta1~1646 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=0e31b4ed2646b2330aad33b959a527c1bbfe6b11;p=gostls13.git debug/dwarf: factor finding unit containing entry offset This factors out the code for finding which unit contains an offset in the "info" section. The new code also replaces linear search with a binary search. The line table reader will also need this functionality. Change-Id: I2076e4fc6719b6f06fd2796cbbc7548ec1876cb3 Reviewed-on: https://go-review.googlesource.com/6733 Reviewed-by: Rob Pike Reviewed-by: Ian Lance Taylor --- diff --git a/src/debug/dwarf/entry.go b/src/debug/dwarf/entry.go index 665c6840d4..d459f30519 100644 --- a/src/debug/dwarf/entry.go +++ b/src/debug/dwarf/entry.go @@ -308,18 +308,13 @@ func (r *Reader) Seek(off Offset) { return } - // TODO(rsc): binary search (maybe a new package) - var i int - var u *unit - for i = range d.unit { - u = &d.unit[i] - if u.off <= off && off < u.off+Offset(len(u.data)) { - r.unit = i - r.b = makeBuf(r.d, u, "info", off, u.data[off-u.off:]) - return - } + i := d.offsetToUnit(off) + if i == -1 { + r.err = errors.New("offset out of range") } - r.err = errors.New("offset out of range") + u := &d.unit[i] + r.unit = i + r.b = makeBuf(r.d, u, "info", off, u.data[off-u.off:]) } // maybeNextUnit advances to the next unit if this one is finished. diff --git a/src/debug/dwarf/unit.go b/src/debug/dwarf/unit.go index 0fbc8e0825..85c44bbdda 100644 --- a/src/debug/dwarf/unit.go +++ b/src/debug/dwarf/unit.go @@ -4,7 +4,10 @@ package dwarf -import "strconv" +import ( + "sort" + "strconv" +) // DWARF debug info is split into a sequence of compilation units. // Each unit has its own abbreviation table and address size. @@ -88,3 +91,20 @@ func (d *Data) parseUnits() ([]unit, error) { } return units, nil } + +// offsetToUnit returns the index of the unit containing offset off. +// It returns -1 if no unit contains this offset. +func (d *Data) offsetToUnit(off Offset) int { + // Find the unit after off + next := sort.Search(len(d.unit), func(i int) bool { + return d.unit[i].off > off + }) + if next == 0 { + return -1 + } + u := &d.unit[next-1] + if u.off <= off && off < u.off+Offset(len(u.data)) { + return next - 1 + } + return -1 +}