aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKeith Randall <khr@golang.org>2016-12-01 10:10:17 -0800
committerKeith Randall <khr@golang.org>2016-12-01 18:20:04 +0000
commit3c2e4ed8d31e65556e936bf394a47e644605d23d (patch)
tree0f9c261abca52d10618e5c2b996579929a2546ed /src
parent612469ab0b57bb53d1f054e37b64a63c08d8c6db (diff)
downloadgo-3c2e4ed8d31e65556e936bf394a47e644605d23d.tar.xz
cmd/objdump: copy gosym.PCValue into internal package
... so we don't have to export gosym.PCValue. Change-Id: Ie8f196d5e5ab63e3e69d1d7b4bfbbf32b7b5e4f5 Reviewed-on: https://go-review.googlesource.com/33791 Run-TryBot: Keith Randall <khr@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
Diffstat (limited to 'src')
-rw-r--r--src/cmd/internal/objfile/goobj.go51
-rw-r--r--src/debug/gosym/pclntab.go7
2 files changed, 49 insertions, 9 deletions
diff --git a/src/cmd/internal/objfile/goobj.go b/src/cmd/internal/objfile/goobj.go
index 230137e0f5..c04987cc82 100644
--- a/src/cmd/internal/objfile/goobj.go
+++ b/src/cmd/internal/objfile/goobj.go
@@ -114,14 +114,14 @@ func (f *goobjFile) PCToLine(pc uint64) (string, int, *gosym.Func) {
if err != nil {
return "", 0, nil
}
- fileID := gosym.PCValue(pcfile, pc-uint64(s.Data.Offset), arch.MinLC)
+ fileID := int(pcValue(pcfile, pc-uint64(s.Data.Offset), arch))
fileName := s.Func.File[fileID]
pcline := make([]byte, s.Func.PCLine.Size)
_, err = f.f.ReadAt(pcline, s.Func.PCLine.Offset)
if err != nil {
return "", 0, nil
}
- line := gosym.PCValue(pcline, pc-uint64(s.Data.Offset), arch.MinLC)
+ line := int(pcValue(pcline, pc-uint64(s.Data.Offset), arch))
// Note: we provide only the name in the Func structure.
// We could provide more if needed.
return fileName, line, &gosym.Func{Sym: &gosym.Sym{Name: s.Name}}
@@ -129,6 +129,53 @@ func (f *goobjFile) PCToLine(pc uint64) (string, int, *gosym.Func) {
return "", 0, nil
}
+// pcValue looks up the given PC in a pc value table. target is the
+// offset of the pc from the entry point.
+func pcValue(tab []byte, target uint64, arch *sys.Arch) int32 {
+ val := int32(-1)
+ var pc uint64
+ for step(&tab, &pc, &val, pc == 0, arch) {
+ if target < pc {
+ return val
+ }
+ }
+ return -1
+}
+
+// step advances to the next pc, value pair in the encoded table.
+func step(p *[]byte, pc *uint64, val *int32, first bool, arch *sys.Arch) bool {
+ uvdelta := readvarint(p)
+ if uvdelta == 0 && !first {
+ return false
+ }
+ if uvdelta&1 != 0 {
+ uvdelta = ^(uvdelta >> 1)
+ } else {
+ uvdelta >>= 1
+ }
+ vdelta := int32(uvdelta)
+ pcdelta := readvarint(p) * uint32(arch.MinLC)
+ *pc += uint64(pcdelta)
+ *val += vdelta
+ return true
+}
+
+// readvarint reads, removes, and returns a varint from *p.
+func readvarint(p *[]byte) uint32 {
+ var v, shift uint32
+ s := *p
+ for shift = 0; ; shift += 7 {
+ b := s[0]
+ s = s[1:]
+ v |= (uint32(b) & 0x7F) << shift
+ if b&0x80 == 0 {
+ break
+ }
+ }
+ *p = s
+ return v
+}
+
// We treat the whole object file as the text section.
func (f *goobjFile) text() (textStart uint64, text []byte, err error) {
var info os.FileInfo
diff --git a/src/debug/gosym/pclntab.go b/src/debug/gosym/pclntab.go
index e94ed19d7d..ba1cf8b699 100644
--- a/src/debug/gosym/pclntab.go
+++ b/src/debug/gosym/pclntab.go
@@ -291,13 +291,6 @@ func (t *LineTable) step(p *[]byte, pc *uint64, val *int32, first bool) bool {
return true
}
-// PCValue looks up the given PC in a pc value table. target is the
-// offset of the pc from the entry point.
-func PCValue(tab []byte, target uint64, quantum int) int {
- t := LineTable{Data: tab, quantum: uint32(quantum)}
- return int(t.pcvalue(0, 0, target))
-}
-
// pcvalue reports the value associated with the target pc.
// off is the offset to the beginning of the pc-value table,
// and entry is the start PC for the corresponding function.