summaryrefslogtreecommitdiff
path: root/src/pkg/debug/gosym/pclntab.go
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2009-09-01 16:11:17 -0700
committerRuss Cox <rsc@golang.org>2009-09-01 16:11:17 -0700
commit83734d684ace400bbde03caa110e087fce3cafe1 (patch)
tree176c5eb8213fe7caf5b417a59b10fafbb817a068 /src/pkg/debug/gosym/pclntab.go
parent369a523fd9053f42844adc08022d88afbed6abb0 (diff)
downloadgolang-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.go85
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};
+}