diff options
author | Russ Cox <rsc@golang.org> | 2009-09-01 16:11:17 -0700 |
---|---|---|
committer | Russ Cox <rsc@golang.org> | 2009-09-01 16:11:17 -0700 |
commit | 83734d684ace400bbde03caa110e087fce3cafe1 (patch) | |
tree | 176c5eb8213fe7caf5b417a59b10fafbb817a068 /src/pkg/debug/gosym/pclntab.go | |
parent | 369a523fd9053f42844adc08022d88afbed6abb0 (diff) | |
download | golang-83734d684ace400bbde03caa110e087fce3cafe1.tar.gz |
import debug/gosym from usr/austin/sym
R=austin
DELTA=958 (956 added, 0 deleted, 2 changed)
OCL=34180
CL=34212
Diffstat (limited to 'src/pkg/debug/gosym/pclntab.go')
-rw-r--r-- | src/pkg/debug/gosym/pclntab.go | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/src/pkg/debug/gosym/pclntab.go b/src/pkg/debug/gosym/pclntab.go new file mode 100644 index 000000000..9671d9aa0 --- /dev/null +++ b/src/pkg/debug/gosym/pclntab.go @@ -0,0 +1,85 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +/* + * Line tables + */ + +package gosym + +import ( + "debug/binary"; + "io"; +) + +type LineTable struct { + Data []byte; + PC uint64; + Line int; +} + +// TODO(rsc): Need to pull in quantum from architecture definition. +const quantum = 1; + +func (t *LineTable) parse(targetPC uint64, targetLine int) (b []byte, pc uint64, line int) { + // The PC/line table can be thought of as a sequence of + // <pc update>* <line update> + // batches. Each update batch results in a (pc, line) pair, + // where line applies to every PC from pc up to but not + // including the pc of the next pair. + // + // Here we process each update individually, which simplifies + // the code, but makes the corner cases more confusing. + b, pc, line = t.Data, t.PC, t.Line; + for pc <= targetPC && line != targetLine && len(b) > 0 { + code := b[0]; + b = b[1:len(b)]; + switch { + case code == 0: + if len(b) < 4 { + b = b[0:0]; + break; + } + val := binary.BigEndian.Uint32(b); + b = b[4:len(b)]; + line += int(val); + case code <= 64: + line += int(code); + case code <= 128: + line -= int(code - 64); + default: + pc += quantum*uint64(code - 128); + continue; + } + pc += quantum; + } + return b, pc, line; +} + +func (t *LineTable) slice(pc uint64) *LineTable { + data, pc, line := t.parse(pc, -1); + return &LineTable{data, pc, line}; +} + +func (t *LineTable) PCToLine(pc uint64) int { + b, pc, line := t.parse(pc, -1); + return line; +} + +func (t *LineTable) LineToPC(line int, maxpc uint64) uint64 { + b, pc, line1 := t.parse(maxpc, line); + if line1 != line { + return 0; + } + // Subtract quantum from PC to account for post-line increment + return pc - quantum; +} + +// NewLineTable returns a new PC/line table +// corresponding to the encoded data. +// Text must be the start address of the +// corresponding text segment. +func NewLineTable(data []byte, text uint64) *LineTable { + return &LineTable{data, text, 0}; +} |