5.3 COFF行番号

COFF行番号は、ソース ファイル内のコードと行番号の間の関係を示します。Microsoft形式のCOFF行番号は標準COFFのものに類似していますが、1つのセクションを複数のソース ファイルの行番号に関連付けることを許す拡張がなされています。

COFF行番号は固定長レコードの配列からなります。配列の位置(ファイル オフセット)とサイズは、セクション ヘッダで指定されています。各行番号レコードの形式は以下の通りです。

オフセット サイズ フィールド 解説
0 4 Type (*) 2つのフィールドSymbol Table IndexとRVAの共用体です。Symbol Table IndexとRVAのどちらが使われるかは、Linenumberの値に依存します。
4 2 Linenumber ゼロでない場合、このフィールドは1をベースとする行番号を指定します。ゼロの場合、Typeフィールドが関数のSymbol Table Indexであるものと解釈されます。

Typeフィールドは2つの4バイトフィールドSymbol Table IndexとRVAの共用体です。

オフセット サイズ フィールド 解説
0 4 SymbolTableIndex Linenumber が0のときに使用されます。関数のシンボル テーブル エントリのインデックスです。この形式は行番号レコードのグループが指す関数を示すために使われます。
0 4 VirtualAddress Linenumber が0でないときに使用されます。示されたソース行に対応する実行コードの相対仮想アドレスです。オブジェクト ファイルでは、これはセクション内部の仮想アドレスを含んでいます。

行番号レコードはここで、Linenumberフィールドに0をセットしてSymbol Table内の関数定義を指すようにするか、正の整数(行番号)およびオブジェクト コードの対応するアドレスを与えることによって標準行番号エントリとして使うことができます。

行番号エントリのグループは常に先頭の形式である関数シンボルのインデックスで始まります。これがセクション内の最初の行番号レコードである場合には、セクションのCOMDATフラグがセットされていれば、それはまた関数のCOMDATシンボル名でもあります(5.5.6節「COMDATセクション」参照)。関数のSymbol Table内の補助レコードにはLinenumbersフィールドへのポインタがあり、これはこの同じ行番号レコードを指します。

関数を識別するレコードのあとには、実際の行番号情報を与える任意の数の行番号エントリが続きます(ゼロより大きなLinenumber)。 これらのエントリは、1をベースとした関数の先頭に相対のものであり、最初の1行を除く関数内のすべてのソース行を表します。

たとえば、次の例の最初の行番号レコードはReverseSign関数(ReverseSignのSymbol Table Index、Linenumberは0に設定)を指します。その後に、示されているソース行に対応するLinenumberの値が1、2、および3のレコードが続きます。

// some code precedes ReverseSign function
intReverseSign(int i)
1:{
2:return -1 * i;
3:}

戻る