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