src/pkg/debug/gosym/pclntab.go - The Go Programming Language

Golang

Source file src/pkg/debug/gosym/pclntab.go

     1	// Copyright 2009 The Go Authors.  All rights reserved.
     2	// Use of this source code is governed by a BSD-style
     3	// license that can be found in the LICENSE file.
     4	
     5	/*
     6	 * Line tables
     7	 */
     8	
     9	package gosym
    10	
    11	import "encoding/binary"
    12	
    13	type LineTable struct {
    14		Data []byte
    15		PC   uint64
    16		Line int
    17	}
    18	
    19	// TODO(rsc): Need to pull in quantum from architecture definition.
    20	const quantum = 1
    21	
    22	func (t *LineTable) parse(targetPC uint64, targetLine int) (b []byte, pc uint64, line int) {
    23		// The PC/line table can be thought of as a sequence of
    24		//  <pc update>* <line update>
    25		// batches.  Each update batch results in a (pc, line) pair,
    26		// where line applies to every PC from pc up to but not
    27		// including the pc of the next pair.
    28		//
    29		// Here we process each update individually, which simplifies
    30		// the code, but makes the corner cases more confusing.
    31		b, pc, line = t.Data, t.PC, t.Line
    32		for pc <= targetPC && line != targetLine && len(b) > 0 {
    33			code := b[0]
    34			b = b[1:]
    35			switch {
    36			case code == 0:
    37				if len(b) < 4 {
    38					b = b[0:0]
    39					break
    40				}
    41				val := binary.BigEndian.Uint32(b)
    42				b = b[4:]
    43				line += int(val)
    44			case code <= 64:
    45				line += int(code)
    46			case code <= 128:
    47				line -= int(code - 64)
    48			default:
    49				pc += quantum * uint64(code-128)
    50				continue
    51			}
    52			pc += quantum
    53		}
    54		return b, pc, line
    55	}
    56	
    57	func (t *LineTable) slice(pc uint64) *LineTable {
    58		data, pc, line := t.parse(pc, -1)
    59		return &LineTable{data, pc, line}
    60	}
    61	
    62	func (t *LineTable) PCToLine(pc uint64) int {
    63		_, _, line := t.parse(pc, -1)
    64		return line
    65	}
    66	
    67	func (t *LineTable) LineToPC(line int, maxpc uint64) uint64 {
    68		_, pc, line1 := t.parse(maxpc, line)
    69		if line1 != line {
    70			return 0
    71		}
    72		// Subtract quantum from PC to account for post-line increment
    73		return pc - quantum
    74	}
    75	
    76	// NewLineTable returns a new PC/line table
    77	// corresponding to the encoded data.
    78	// Text must be the start address of the
    79	// corresponding text segment.
    80	func NewLineTable(data []byte, text uint64) *LineTable {
    81		return &LineTable{data, text, 0}
    82	}