]> Cypherpunks repositories - gostls13.git/commitdiff
debug/dwarf: factor finding unit containing entry offset
authorAustin Clements <austin@google.com>
Wed, 4 Mar 2015 01:53:40 +0000 (20:53 -0500)
committerAustin Clements <austin@google.com>
Tue, 10 Mar 2015 02:32:37 +0000 (02:32 +0000)
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 <r@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
src/debug/dwarf/entry.go
src/debug/dwarf/unit.go

index 665c6840d43024435a0fe3e77c1ccc7fc37ffd88..d459f30519cf9d7345f8e518f46326ec9a0d06b5 100644 (file)
@@ -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.
index 0fbc8e0825bb0a429e33c0892cdb1c5729a39e61..85c44bbddabc79652636b92c779ae5ddba70dec2 100644 (file)
@@ -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
+}