私は、シンボルテーブルがELFの.dataセクションとどのように関連しているかを理解しようとしています。まず、いくつかの仮定に基づいて始めます。
記号は、関数または変数を人間が読み取ることができる(または「ソースファイルに書かれているように」)表現したもので、実際のバイナリ値(CPUが動作する値)にマッピングされます。
ここに例があります。
//simple.c
int var_global_init = 5;
int main(void)
{
return 0;
}
ビルドしてバイナリを確認しましょう:
$ gcc simple.c -o simple
$ objdump -t simple | grep var_global_init
0000000000201010 g O .data 0000000000000004 var_global_init
.data
ELFファイルセクションのシンボルを一覧表示します。 20ページELF文書
この部分を次.data
のように定義します。
このセクションには、プログラムのメモリイメージに寄与する初期化データが含まれています。
まあ、それは適切です。だから私は自分に尋ねたDoes this mean that the symbol table is embedded in the .data section?
。しかし、次の例はこれを反証しているようです。
$ readelf -s simple
Symbol table '.symtab' contains 66 entries:
....
50: 0000000000201010 4 OBJECT GLOBAL DEFAULT 23 var_global_init
readelf
.symtab
ELFにこのシンボルを保持する専用セクションがあることを示します。
この.data
セクションには実際のシンボルテーブルが必要ですか?最初の例は、data
セクションに1つがあることを示していますが、バイナリ値のみを実行できる必要はありませんか?
検査によってhexdump
単一の項目しか検出できないため、私の概念が間違っているか、一部が嘘をついています。 :)
答え1
この.data
セクションにはデータ自体が含まれています。つまり値5を保持する4バイトint
。この.symtab
セクションでは記号、つまりバイナリファイルの各セクション名は、そのvar_global_init
セクション.data
に格納されている4バイトを指します。
これが1つのエントリ、つまりシンボルテーブルに1つのシンボルのみが表示される理由です。ただし、名前を値に変換するには、次の2つの部分が必要です。シンボルテーブルはシンボルに対応する値を見つける場所を示し、var_global_init
データ部分にはその値の記憶領域が含まれる。