github.com/shogo82148/std@v1.22.1-0.20240327122250-4e474527810c/debug/dwarf/line.go (about)

     1  // Copyright 2015 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  package dwarf
     6  
     7  import (
     8  	"github.com/shogo82148/std/errors"
     9  )
    10  
    11  // LineReaderは、単一のコンパイルユニットのDWARF「line」セクションから [LineEntry] 構造体のシーケンスを読み取ります。
    12  // [LineEntry] は、PCの増加順に発生し、各 [LineEntry] は、その [LineEntry] のPCから次の [LineEntry] のPCの直前までの命令のメタデータを提供します。
    13  // 最後のエントリには、[LineEntry.EndSequence] フィールドが設定されます。
    14  type LineReader struct {
    15  	buf buf
    16  
    17  	// Original .debug_line section data. Used by Seek.
    18  	section []byte
    19  
    20  	str     []byte
    21  	lineStr []byte
    22  
    23  	// Header information
    24  	version              uint16
    25  	addrsize             int
    26  	segmentSelectorSize  int
    27  	minInstructionLength int
    28  	maxOpsPerInstruction int
    29  	defaultIsStmt        bool
    30  	lineBase             int
    31  	lineRange            int
    32  	opcodeBase           int
    33  	opcodeLengths        []int
    34  	directories          []string
    35  	fileEntries          []*LineFile
    36  
    37  	programOffset Offset
    38  	endOffset     Offset
    39  
    40  	initialFileEntries int
    41  
    42  	// Current line number program state machine registers
    43  	state     LineEntry
    44  	fileIndex int
    45  }
    46  
    47  // LineEntryは、DWARF行テーブル内の行を表します。
    48  type LineEntry struct {
    49  	// Addressは、コンパイラによって生成されたマシン命令のプログラムカウンター値です。
    50  	// このLineEntryは、Addressから次のLineEntryのAddressの直前までの各命令に適用されます。
    51  	Address uint64
    52  
    53  	// OpIndexは、VLIW命令内の操作のインデックスです。
    54  	// 最初の操作のインデックスは0です。非VLIWアーキテクチャの場合、常に0になります。
    55  	// AddressとOpIndexは、命令ストリーム内の任意の個々の操作を参照できる操作ポインターを形成します。
    56  	OpIndex int
    57  
    58  	// Fileは、これらの命令に対応するソースファイルです。
    59  	File *LineFile
    60  
    61  	// Lineは、これらの命令に対応するソースコードの行番号です。
    62  	// 行番号は1から始まります。これらの命令がどのソース行にも関連付けられていない場合は、0になる場合があります。
    63  	Line int
    64  
    65  	// Columnは、これらの命令のソース行内の列番号です。
    66  	// 列番号は1から始まります。行の「左端」を示すために0になる場合があります。
    67  	Column int
    68  
    69  	// IsStmtは、Addressが推奨されるブレークポイントの場所であることを示します。
    70  	// 例えば、行の始まり、文の始まり、または文の明確な部分などです。
    71  	IsStmt bool
    72  
    73  	// BasicBlockは、Addressが基本ブロックの開始であることを示します。
    74  	BasicBlock bool
    75  
    76  	// PrologueEndは、Addressが、含まれる関数へのエントリにブレークポイントを設定するために、
    77  	// 実行を一時停止する必要があるPCの1つ(可能性がある)であることを示します。
    78  	//
    79  	// DWARF 3で追加されました。
    80  	PrologueEnd bool
    81  
    82  	// EpilogueBeginは、Addressが、この関数からの終了時にブレークポイントを設定するために、
    83  	// 実行を一時停止する必要があるPCの1つ(可能性がある)であることを示します。
    84  	//
    85  	// DWARF 3で追加されました。
    86  	EpilogueBegin bool
    87  
    88  	// ISAは、これらの命令の命令セットアーキテクチャを表します。
    89  	// 可能なISA値は、適用可能なABI仕様によって定義される必要があります。
    90  	//
    91  	// DWARF 3で追加されました。
    92  	ISA int
    93  
    94  	// Discriminatorは、これらの命令が属するブロックを示す任意の整数です。
    95  	// これにより、同じソースファイル、行、列を持つ複数のブロックを区別できます。
    96  	// 特定のソース位置に1つのブロックしか存在しない場合、0にする必要があります。
    97  	//
    98  	// DWARF 3で追加されました。
    99  	Discriminator int
   100  
   101  	// EndSequenceは、Addressがターゲットマシン命令のシーケンスの終わりの直後の最初のバイトであることを示します。
   102  	// 設定されている場合、このフィールドとAddressフィールドのみが有意です。
   103  	// 行番号テーブルには、複数の可能性のある不連続な命令シーケンスの情報が含まれる場合があります。
   104  	// 行テーブルの最後のエントリには、常にEndSequenceが設定されている必要があります。
   105  	EndSequence bool
   106  }
   107  
   108  // LineFileは、DWARF行テーブルエントリによって参照されるソースファイルです。
   109  type LineFile struct {
   110  	Name   string
   111  	Mtime  uint64
   112  	Length int
   113  }
   114  
   115  // LineReaderは、[TagCompileUnit] を持つ [Entry] cuの行テーブルのための新しいリーダーを返します。
   116  //
   117  // このコンパイルユニットに行テーブルがない場合、nil、nilを返します。
   118  func (d *Data) LineReader(cu *Entry) (*LineReader, error)
   119  
   120  // Nextは、この行テーブルの次の行を*entryに設定し、次の行に移動します。
   121  // もうエントリがなく、行テーブルが適切に終了している場合、[io.EOF] を返します。
   122  //
   123  // 行は常にentry.Addressの増加順に並んでいますが、entry.Lineは前後に移動する場合があります。
   124  func (r *LineReader) Next(entry *LineEntry) error
   125  
   126  // LineReaderPosは、行テーブル内の位置を表します。
   127  type LineReaderPos struct {
   128  	// off is the current offset in the DWARF line section.
   129  	off Offset
   130  	// numFileEntries is the length of fileEntries.
   131  	numFileEntries int
   132  	// state and fileIndex are the statement machine state at
   133  	// offset off.
   134  	state     LineEntry
   135  	fileIndex int
   136  }
   137  
   138  // Tellは、行テーブル内の現在の位置を返します。
   139  func (r *LineReader) Tell() LineReaderPos
   140  
   141  // Seekは、[LineReader.Tell] によって返された位置に行テーブルリーダーを復元します。
   142  //
   143  // 引数posは、この行テーブルの [LineReader.Tell] 呼び出しによって返されたものである必要があります。
   144  func (r *LineReader) Seek(pos LineReaderPos)
   145  
   146  // Resetは、行テーブルリーダーを行テーブルの先頭に再配置します。
   147  func (r *LineReader) Reset()
   148  
   149  // Filesは、現在の行テーブルの位置に基づいて、このコンパイルユニットのファイル名テーブルを返します。
   150  // ファイル名テーブルは、[AttrDeclFile] などのこのコンパイルユニットの属性から参照される場合があります。
   151  //
   152  // Entry 0は常にnilです。なぜなら、ファイルインデックス0は「ファイルなし」を表すからです。
   153  //
   154  // コンパイルユニットのファイル名テーブルは固定されていません。Filesは、
   155  // 行テーブルの現在の位置に基づいてファイルテーブルを返します。
   156  // これにより、行テーブルの以前の位置のファイルテーブルよりもエントリが多く含まれる場合がありますが、
   157  // 既存のエントリは変更されません。
   158  func (r *LineReader) Files() []*LineFile
   159  
   160  // ErrUnknownPCは、LineReader.ScanPCが行テーブルのエントリによってカバーされていないPCを検出した場合に返されるエラーです。
   161  var ErrUnknownPC = errors.New("ErrUnknownPC")
   162  
   163  // SeekPCは、pcを含む [LineEntry] を*entryに設定し、
   164  // 行テーブルの次のエントリに位置を設定します。
   165  // 必要に応じて、pcを検索するために後方にシークします。
   166  //
   167  // pcがこの行テーブルのエントリによってカバーされていない場合、
   168  // SeekPCは [ErrUnknownPC] を返します。この場合、*entryと最終的なシーク位置は未指定です。
   169  //
   170  // DWARF行テーブルは、順次前方スキャンのみを許可します。
   171  // したがって、最悪の場合、これには行テーブルのサイズに比例する時間がかかります。
   172  // 呼び出し側が繰り返し高速なPC検索を行いたい場合は、
   173  // 適切な行テーブルのインデックスを構築する必要があります。
   174  func (r *LineReader) SeekPC(pc uint64, entry *LineEntry) error