ELFフォーマット
Executable and Linkable Format。Linux の実行ファイル・オブジェクトファイル・共有ライブラリの形式。
二面性
ELFの最大の特徴は、プログラムの「リンク」と「実行」に応じた二重構造を持つこと。
- セクション(section) から見る視点: リンク時に使う。
.text(プログラム)、.rodata、.data(書き換え可能な global/static 変数)、.bss。section headers が記述する。 - セグメント(segment) から見る視点: 実行(ロード)時に使う。複数のセクションをまとめたもので、program headers がメタ情報を持つ。
readelfの “Section to Segment mapping” で対応がわかる。
ヘッダ構造
全体は ELF header → program headers → 各 section → section headers の順に並ぶ。
- アーキテクチャでフォーマットが変わる。
i386(x86)はオフセットがu32、x64はu64。先頭16バイトで判別可能。詳細は cpu-architecture-isa。 - program header の
p_filesz(ファイル上サイズ)とp_memsz(メモリ上サイズ)は異なり、.bss(static配列など)の分だけ後者が膨らむ。 - type:
PT_GNU_STACK(スタックの実行可否をシステムに伝える。アセンブラを混ぜると executable flag が付く)、PT_GNU_RELRO(dataセグメントの一部、cpu-side-channel-attacks や pwn で頻出)。
VMAとLMA
- VMA (Virtual Memory Address): プログラム実行時に参照されるアドレス。リンカスクリプト記述の基準。
- LMA (Load Memory Address): プログラムをロードするときに参照されるアドレス。組み込みでは RAM 上のアドレスを指す。
- 通常は両者一致するが、kernel program では異なる。リンカスクリプト(ld の Linker Script)では
.が現在のVMAを示し、AT(<lma>)でLMAを指定する。
関連ツール
readelf/objdump: ELF の解析・逆アセンブル。- gdb:
-g付きでデバッグ情報を付与、gcc -staticでstaticリンク。 - スタックフレーム: 関数呼び出しの局所変数・戻りアドレス領域。
関連: _moc-systems / linux / operating-system-kernel