diff options
| author | Keith Randall <khr@golang.org> | 2016-12-01 10:10:17 -0800 |
|---|---|---|
| committer | Keith Randall <khr@golang.org> | 2016-12-01 18:20:04 +0000 |
| commit | 3c2e4ed8d31e65556e936bf394a47e644605d23d (patch) | |
| tree | 0f9c261abca52d10618e5c2b996579929a2546ed /src | |
| parent | 612469ab0b57bb53d1f054e37b64a63c08d8c6db (diff) | |
| download | go-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.go | 51 | ||||
| -rw-r--r-- | src/debug/gosym/pclntab.go | 7 |
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. |
