ELF(5) | FreeBSD File Formats Manual | ELF(5) |
名称
elf — ELF 実行形式バイナリファイルのフォーマット書式
#include < elf.h>解説
ヘッダファイル < elf.h> は、ELF 実行形式バイナリファイルのフォーマットを定義しています。 ELF には普通の実行可能ファイル、再配置可能なオブジェクトファイル、コアファイル、共有ライブラリがあります。ELF ファイルフォーマットを使っている実行可能ファイルは ELF ヘッダを持ちます。そして、プログラムヘッダテーブルか、セクションヘッダテーブル、あるいはその両方が続きます。 ELF ヘッダは、常にファイルのオフセット 0 にあります。プログラムヘッダテーブルとセクションヘッダテーブルのファイル中のオフセットは、 ELF ヘッダで定義されています。 2 つのテーブルは、ファイルの特徴の残りの部分を記述します。
ネイティブアーキテクチャの ELF バイナリファイルを処理するアプリケーションは、そのソースコードに < elf.h> をインクルードするだけですみます。これらのアプリケーションは、総称名“Elf_xxx”による全タイプと構造体への参照を含む必要があり、“ELF_xxx”によるマクロへの参照を含む必要があるでしょう。このようにして記述されたアプリケーションは、どのようなアーキテクチャであっても、ホストが 32 ビットなのか、あるいは 64 ビットなのかということを気にしないで、コンパイル可能です。
未知のアーキテクチャの ELF ファイルを処理する必要があるアプリケーションは、 < elf.h> ではなく、 < sys/elf32.h> と < sys/elf64.h> の両方をインクルードする必要があります。さらに、全てのタイプと構造体は、“Elf32_xxx”か“Elf64_xxx”によって区別する必要があります。マクロは、“ELF32_xxx”または“ELF64_xxx”によって区別する必要があります。
システムのアーキテクチャがたとえ何であっても、常に < sys/elf_generic.h> だけでなく、 < sys/elf_common.h> もインクルードします。
これらのヘッダファイルでは、上で言及したヘッダを C 構造体として記述し、これに加えて動的セクションと再配置セクションとシンボルテーブルのための構造体を含んでいます。
以下のタイプが、32 ビットアーキテクチャのために使われています:
Elf32_Addr 符号無し 32 ビットプログラムアドレス Elf32_Half 符号無し 16 ビットフィールド Elf32_Lword 符号無し 64 ビットフィールド Elf32_Off 符号無し 32 ビットファイルオフセット Elf32_Sword 符号付き 32 ビットフィールドまたは整数 Elf32_Word 符号無し 32 ビットフィールドまたは整数
64 ビットアーキテクチャ用に以下のタイプが用意されています:
Elf64_Addr 符号無し 64 ビットプログラムアドレス Elf64_Half 符号無し 16 ビットフィールド Elf64_Lword 符号無し 64 ビットフィールド Elf64_Off 符号無し 64 ビットファイルオフセット Elf64_Sword 符号付き 32 ビットフィールド Elf64_Sxword 符号付き 64 ビットフィールドまたは整数 Elf64_Word 符号無し 32 ビットフィールド Elf64_Xword 符号無し 64 ビットフィールドまたは整数
ELF ファイルフォーマットが定義する全てのデータ構造は、関連するクラスのために“自然な”サイズと境界調整のガイドラインに従っています。必要ならば、データ構造は、4 バイトオブジェクトが 4 バイト境界となることを保証するために、構造体のサイズを強制的に 4 の倍数にするとかいった手段で、明示的なパディングを含めます。
ELF ヘッダは、Elf32_Ehdr 型または Elf64_Ehdr 型によって記述されています:
typedef struct { unsigned char e_ident[EI_NIDENT]; Elf32_Half e_type; Elf32_Half e_machine; Elf32_Word e_version; Elf32_Addr e_entry; Elf32_Off e_phoff; Elf32_Off e_shoff; Elf32_Word e_flags; Elf32_Half e_ehsize; Elf32_Half e_phentsize; Elf32_Half e_phnum; Elf32_Half e_shentsize; Elf32_Half e_shnum; Elf32_Half e_shstrndx; } Elf32_Ehdr;
typedef struct { unsigned char e_ident[EI_NIDENT]; Elf64_Half e_type; Elf64_Half e_machine; Elf64_Word e_version; Elf64_Addr e_entry; Elf64_Off e_phoff; Elf64_Off e_shoff; Elf64_Word e_flags; Elf64_Half e_ehsize; Elf64_Half e_phentsize; Elf64_Half e_phnum; Elf64_Half e_shentsize; Elf64_Half e_shnum; Elf64_Half e_shstrndx; } Elf64_Ehdr;
フィールドは、以下の意味を持っています:
- e_ident
-
このバイト配列はファイルをどのように解釈すべきかを指定します。これは、プロセッサまたはファイルの残りの内容から独立しています。この配列中の全要素は、
EI_ で開始するマクロにより名付けられ、また先頭に
ELF がついた値を持ち得ます。以下のマクロが定義されています:
- EI_MAG0
- マジック番号の第 1 のバイト。 ELFMAG0 であることが必要です。
- EI_MAG1
- マジック番号の第 2 のバイト。 ELFMAG1 であることが必要です。
- EI_MAG2
- マジック番号の第 3 のバイト。 ELFMAG2 であることが必要です。
- EI_MAG3
- マジック番号の第 4 のバイト。 ELFMAG3 であることが必要です。
- EI_CLASS
-
第 5 のバイトは、当該のバイナリファイルのアーキテクチャを識別します:
- ELFCLASSNONE
- このクラスは、不当です。
- ELFCLASS32
- これは、32 ビットアーキテクチャを定義します。ファイル空間と仮想アドレス空間が 4 ギガバイトまでにおさまるマシンに対応します。
- ELFCLASS64
- これは、64 ビットアーキテクチャを定義します。
- EI_DATA
-
第 6 のバイトは、ファイルのプロセッサ固有データのエンコーディングを指定します。現在、次のエンコーディングがサポートされています:
- ELFDATANONE
- 未知のデータフォーマット。
- ELFDATA2LSB
- 2 の補数、リトルエンディアン。
- ELFDATA2MSB
- 2 の補数、ビッグエンディアン。
- EI_VERSION
-
ELF 仕様書のバージョンナンバ:
- EV_NONE
- 不当なバージョン。
- EV_CURRENT
- 現在のバージョン。
- EI_OSABI
-
このバイトは、オブジェクトの対象である、オペレーティングシステムと ABI を識別します。他の ELF 構造中のフィールドには、プラットフォーム依存の意味のものがあります。そのようなフィールドの解釈は、このバイトの値で決定されます。次の値が現在定義されています:
- ELFOSABI_SYSV
- UNIX System V ABI。
- ELFOSABI_HPUX
- HP-UX オペレーティングシステム ABI。
- ELFOSABI_NETBSD
- NetBSD オペレーティングシステム ABI。
- ELFOSABI_LINUX
- GNU/Linux オペレーティングシステム ABI。
- ELFOSABI_HURD
- GNU/Hurd オペレーティングシステム ABI。
- ELFOSABI_86OPEN
- 86Open Common IA32 ABI。
- ELFOSABI_SOLARIS
- Solaris オペレーティングシステム ABI。
- ELFOSABI_MONTEREY
- Monterey プロジェクト ABI。
- ELFOSABI_IRIX
- IRIX オペレーティングシステム ABI。
- ELFOSABI_FREEBSD
- FreeBSD オペレーティングシステム ABI。
- ELFOSABI_TRU64
- TRU64 UNIX オペレーティングシステム ABI。
- ELFOSABI_ARM
- ARM アーキテクチャ ABI。
- ELFOSABI_STANDALONE
- Standalone (組み込み) ABI。
- EI_ABIVERSION
- このバイトは、オブジェクトの対象である ABI のバージョンを識別します。このフィールドは、同じ ABI でも、互換性の無いもの同士を区別するために使用されます。バージョン番号の解釈は、EI_OSABI フィールドで識別される ABI に依存します。この仕様に準拠するアプリケーションは、値 0 を使用します。
- EI_PAD
- パディングの始め。これらのバイトは、予約されており、0 にセットされます。ここを読むプログラムは、これを無視する必要があります。将来、現在使っていないバイトに意味が与えられた時には、 EI_PAD の値は変わります。
- EI_BRAND
- アーキテクチャ識別子の始め。
- EI_NIDENT
- e_ident 配列の大きさ。
- e_type
-
構造体のこのメンバは、オブジェクトファイルタイプを識別します:
- ET_NONE
- 未知のタイプ。
- ET_REL
- 再配置可能なファイル。
- ET_EXEC
- 実行可能ファイル。
- ET_DYN
- 共有オブジェクト。
- ET_CORE
- コアファイル。
- e_machine
-
このメンバは、個々のファイルに必要なアーキテクチャを指定します:
- EM_NONE
- 未知のマシン。
- EM_M32
- AT&T WE 32100
- EM_SPARC
- Sun Microsystems SPARC.
- EM_386
- Intel 80386.
- EM_68K
- Motorola 68000
- EM_88K
- Motorola 88000
- EM_486
- Intel 80486
- EM_860
- Intel 80860
- EM_MIPS
- MIPS RS3000 (ビッグエンディアンのみ)
- EM_MIPS_RS4_BE
- MIPS RS4000 (ビッグエンディアンのみ)
- EM_SPARC64
- SPARC v9 64-bit 非公式
- EM_PARISC
- HPPA
- EM_PPC
- PowerPC
- EM_ALPHA
- Compaq [DEC] Alpha
- e_version
-
このメンバは、ファイルバージョンを識別します:
- EV_NONE
- 不当なバージョン。
- EV_CURRENT
- 現在のバージョン。
- e_entry
- このメンバは、システムが最初に制御を移す、つまりプロセスを開始する仮想アドレスを示します。ファイルにエントリポイントがないならば、このメンバは 0 になります。
- e_phoff
- このメンバは、プログラムヘッダテーブルのバイト単位のファイルオフセットを持ちます。
- e_shoff
- このメンバは、セクションヘッダテーブルのバイト単位のファイルオフセットを持ちます。ファイルにセクションヘッダテーブルがないならば、このメンバは 0 になります。
- e_flags
- このメンバは、ファイルに関連する、プロセッサに固有なフラグを持ちます。フラグ名は、EF_`machine_flag' という形式になります。現在、定義されたフラグはありません。
- e_ehsize
- このメンバは、ELF ヘッダのバイト単位の大きさを持ちます。
- e_phentsize
- このメンバは、ファイルのプログラムヘッダテーブルにあるエントリ 1 個分のサイズを持ちます。全てのエントリは、同じ大きさです。
- e_phnum
- このメンバは、プログラムヘッダテーブル中のエントリの個数を持ちます。ファイルが拡張プログラムヘッダ番号付けを使用しているなら、 e_phnum メンバは値 PN_XNUM を含み、プログラムヘッダテーブルエントリの実際の数は、インデックス SHN_UNDEF のセクションヘッダの sh_info メンバに格納されます。 e_phentsize の製品とプログラムヘッダテーブルエントリの数は、バイト単位でプログラムヘッダテーブルのサイズを与えます。ファイルにプログラムヘッダがないなら、 e_phnum は、値 0 を保持します。
- e_shentsize
- このメンバは、セクションヘッダのバイト単位の大きさを持ちます。セクションヘッダは、セクションヘッダテーブルの中の 1 つのエントリです;全てのエントリは、同じ大きさです。
- e_shnum
- このメンバは、セクションヘッダテーブル中のエントリの個数を持ちます。ファイルが拡張セクション番号付けを使用しているなら、 e_shnum メンバは 0 となり、実際のセクション番号は、インデックス SHN_UNDEF のセクションヘッダの sh_size メンバに格納されます。ファイルにセクションヘッダテーブルがないなら、ELF ヘッダの e_shnum と e_shoff フィールドの両方は、0 となります。 e_shentsize の製品とファイル中のセクションの数は、バイト単位でセクションヘッダテーブルのサイズを与えます。
- e_shstrndx
- このメンバは、セクションヘッダテーブルの、セクション名文字列テーブルに結びつけられたエントリへのインデックスを持ちます。拡張されたセクション番号付けが使用されているなら、このフィールドは、値 SHN_XINDEX を保持し、実際のセクションヘッダテーブルのインデックスは、インデックス SHN_UNDEF のセクションヘッダエントリの sh_link フィールドに存在します。ファイルにセクション名文字列テーブルがないならば、このメンバは値 SHN_UNDEF を持ちます。
実行可能ファイルまたは共有オブジェクトファイルのプログラムヘッダテーブルは、構造体の配列です。各構造体は、プログラム実行にシステムが必要とする、セグメント等の情報を記述します。オブジェクトファイルの セグメント は、1 つ以上の セクション を含みます。プログラムヘッダは、実行可能ファイルと共有オブジェクトファイルだけで意味があります。ファイルは、ELF ヘッダの e_phentsize と e_phnum メンバでそれ自身のプログラムヘッダサイズを指定します。 ELF 実行形式のヘッダと同様に、プログラムヘッダもアーキテクチャに従い異なるバージョンを持ちます:
typedef struct { Elf32_Word p_type; Elf32_Off p_offset; Elf32_Addr p_vaddr; Elf32_Addr p_paddr; Elf32_Word p_filesz; Elf32_Word p_memsz; Elf32_Word p_flags; Elf32_Word p_align; } Elf32_Phdr;
typedef struct { Elf64_Word p_type; Elf64_Word p_flags; Elf64_Off p_offset; Elf64_Addr p_vaddr; Elf64_Addr p_paddr; Elf64_Xword p_filesz; Elf64_Xword p_memsz; Elf64_Xword p_align; } Elf64_Phdr;
32 ビットと 64 ビットのプログラムヘッダの間の主な差は、構造体中の p_flags メンバの位置だけです。
- p_type
-
構造体 Phdr のこのメンバは、この配列要素が記述しているセグメントの種類を示し、どのように配列要素を解釈すべきかを示します。
- PT_NULL
- この配列要素は使っていません。また、他のメンバの値は未定義です。これにより、プログラムヘッダ中に無視されるエントリを持てます。
- PT_LOAD
- この配列要素は、ロード可能なセグメントを指定します。これは p_filesz と p_memsz で記述されます。ファイルからのバイトは、メモリセグメントの先頭にマップされます。セグメントのメモリサイズ ( p_memsz) がファイルサイズ ( p_filesz) より大きいならば、“余分な”バイトは、値 0 を持って、セグメントの初期化された領域に続くものと定義されます。ファイルサイズは、メモリサイズを越えてはなりません。プログラムヘッダテーブルの中のロード可能なセグメントエントリは、昇順で現れます。そして、 p_vaddr メンバでソートされます。
- PT_DYNAMIC
- この配列要素は、動的リンク情報を指定します。
- PT_INTERP
- この配列要素は、インタプリタとして起動するヌル文字で終わるパス名の場所と大きさを指定します。このセグメントタイプは、実行可能ファイルのみで意味があります (本セグメントタイプは、共有オブジェクト中にあるかもしれません)。本セグメントは、ファイル中で複数個存在してはなりません。存在する場合、全ロード可能セグメントエントリに先行する必要があります。
- PT_NOTE
- この配列要素は、補助情報のために場所と大きさを指定します。
- PT_SHLIB
- このセグメントタイプは、予約されており、明記されていないセマンティクスを持ちます。このタイプの配列要素を含むプログラムは、ABI に従いません。
- PT_PHDR
- この配列要素が存在する場合、ファイル中とメモリイメージ中における、プログラムヘッダテーブル自身の位置と大きさを指定します。本セグメントタイプは、ファイル中で複数個存在してはなりません。さらに、プログラムヘッダテーブルがプログラムのメモリイメージに含まれる場合のみ、存在が許されます。存在する場合、全ロード可能セグメントエントリに先行する必要があります。
- PT_LOPROC
- この値から PT_HIPROC 以下は、プロセッサ固有のセマンティクスのために予約されています。
- PT_HIPROC
- この値から PT_LOPROC 以上は、プロセッサ固有のセマンティクスのために予約されています。
- p_offset
- このメンバは、セグメントの最初のバイトへの、ファイル先頭からのオフセットを持ちます。
- p_vaddr
- このメンバは、セグメントの最初のバイトがメモリで存在する仮想アドレスを持ちます。
- p_paddr
- 物理アドレッシングのシステム上では、このメンバは、セグメントの物理アドレスのために予約されています。 BSD では、本メンバは使されず、0 である必要があります。
- p_filesz
- このメンバは、セグメントのファイルイメージのバイト数を持ちます。 0 であるかもしれません。
- p_memsz
- このメンバは、セグメントのメモリイメージのバイト数を持ちます。 0 であるかもしれません。
- p_flags
-
このメンバは、セグメントに関したフラグを持ちます。
- PF_X
- 実行可能セグメント。
- PF_W
- 書き込み可能なセグメント。
- PF_R
- 読み込み可能なセグメント。
テキストセグメントは、一般にフラグ PF_X と PF_R を持ちます。データセグメントは、一般に PF_X, PF_W と PF_R を持ちます。
- p_align
- このメンバは、メモリ中およびファイル中でセグメントが整列すべき値を持ちます。ロード可能なプロセスは、 p_vaddr と p_offset をページサイズで割った余りに適合する値を持つ必要があります。 0 と 1 の値は、境界調整が不要であることを意味します。そうでない場合、 p_align は、正 (2 の整数乗) である必要があります。そして、 p_vaddr は p_offset を p_align で割った余りと等しい必要があります。
ファイルのセクションヘッダテーブルは、全てのファイルのセクションの位置決定を可能とします。セクションヘッダテーブルは、Elf32_Shdr または Elf64_Shdr 構造体の配列です。 ELF ヘッダの e_shoff メンバは、セクションヘッダテーブルの、ファイル先頭からのバイトオフセットを与えます。 e_shnum は、セクションヘッダテーブルのエントリ数を持ちます。 e_shentsize は、各エントリの大きさをバイトで持ちます。
セクションヘッダテーブルインデックスは、この配列の添字です。セクションヘッダテーブルインデックスには、予約のものがあります。オブジェクトファイルには、次の特別なインデックスにはセクションがありません:
- SHN_UNDEF
- この値は、未定義か、存在しないか、無関係であるか、意味がないセクション参照を示します。例えば、セクション番号 SHN_UNDEF からの相対で“定義”されるシンボルは、未定義のシンボルです。
- SHN_LORESERVE
- この値は、予約のインデックスの範囲の下限を指定します。
- SHN_LOPROC
- この値から SHN_HIPROC 以下は、プロセッサ固有のセマンティクスのために予約されています。
- SHN_HIPROC
- この値から SHN_LOPROC 以上は、プロセッサ固有のセマンティクスのために予約されています。
- SHN_ABS
- この値は、対応する参照が絶対値であることを指定します。例えば、セクション番号 SHN_ABS からの相対で定義されるシンボルは、絶対的な数値を持ち、再配置によって影響を受けません。
- SHN_COMMON
- このセクションからの相対で定義されるシンボルは、共通シンボルであり、 Fortran の COMMON や領域が確保されていない C の外部変数が該当します。
- SHN_HIRESERVE
- この値は、予約インデックス範囲の上限を指定します。この範囲は、 SHN_LORESERVE と SHN_HIRESERVE の間であり、両端を含みます。セクションヘッダテーブルは、予約のインデックスのためにエントリを含みません。
セクションヘッダは、以下の構造体を持ちます:
typedef struct { Elf32_Word sh_name; Elf32_Word sh_type; Elf32_Word sh_flags; Elf32_Addr sh_addr; Elf32_Off sh_offset; Elf32_Word sh_size; Elf32_Word sh_link; Elf32_Word sh_info; Elf32_Word sh_addralign; Elf32_Word sh_entsize; } Elf32_Shdr;
typedef struct { Elf64_Word sh_name; Elf64_Word sh_type; Elf64_Xword sh_flags; Elf64_Addr sh_addr; Elf64_Off sh_offset; Elf64_Xword sh_size; Elf64_Word sh_link; Elf64_Word sh_info; Elf64_Xword sh_addralign; Elf64_Xword sh_entsize; } Elf64_Shdr;
- sh_name
- このメンバは、セクションの名前を指定します。その値は、セクションヘッダ文字列テーブルセクションへのインデックスであり、ヌル文字で終わる文字列の場所を与えます。
- sh_type
-
このメンバは、セクションの内容とセマンティクスを分類します。
- SHT_NULL
- この値は、セクションヘッダが不活性であることを示します。関連づけられたセクションを持ちません。セクションヘッダの他のメンバは、未定義値を持ちます。
- SHT_PROGBITS
- このセクションは、プログラムによって定義される情報を持ちます。フォーマットと意味は、プログラムだけによってのみ決定されます。
- SHT_SYMTAB
- このセクションは、シンボルテーブルを持ちます。一般的に、 SHT_SYMTAB はリンクエディットのためのシンボルを提供します。これはまた、動的リンクにも使用可能です。これは完全なシンボルテーブルであるため、動的リンクのためには不必要な多くのシンボルを含む場合があります。オブジェクトファイルは、 SHN_DYNSYM セクションも含むことができます。
- SHT_STRTAB
- このセクションは、文字列テーブルを持ちます。オブジェクトファイルは、複数の文字列テーブルセクションを持ち得ます。
- SHT_RELA
- このセクションは、明示的な加数を持つ、再配置エントリを持ちます。例えば、オブジェクトファイルの 32 ビットクラスのタイプ Elf32_Rela が該当します。オブジェクトは、複数の再配置セクションを持ち得ます。
- SHT_HASH
- このセクションは、シンボルハッシュテーブルを持ちます。動的リンクに関連する全オブジェクトは、シンボルハッシュテーブルを含む必要があります。オブジェクトファイルは、単一のハッシュテーブルのみを持ち得ます。
- SHT_DYNAMIC
- このセクションは、動的リンクのために情報を持ちます。オブジェクトファイルは、単一の動的セクションのみを持ち得ます。
- SHT_NOTE
- このセクションは、いくばくかの方法でファイルに印をする情報を持ちます。
- SHT_NOBITS
- このタイプのセクションは、ファイル中の空間を占有しませんが、 SHN_PROGBITS に似ています。このセクションはバイトを含みませんが、 sh_offset メンバは概念上のファイルオフセットを含みます。
- SHT_REL
- このセクションは、明示的な加数無しの再配置オフセットを持ちます。例えば、オブジェクトファイルの 32 ビットクラスのタイプ Elf32_Rel が該当します。オブジェクトファイルは、複数の再配置セクションを持ち得ます。
- SHT_SHLIB
- このセクションは、予約されており、明記されていないセマンティクスを持ちます。
- SHT_DYNSYM
- このセクションは、動的リンクシンボルの最小のセットを持ちます。オブジェクトファイルは、 SHN_SYMTAB セクションも含むことができます。
- SHT_LOPROC
- この値から SHT_HIPROC 以下は、プロセッサ固有のセマンティクスのために予約されています。
- SHT_HIPROC
- この値から SHT_LOPROC 以上は、プロセッサ固有のセマンティクスのために予約されています。
- SHT_LOUSER
- この値は、アプリケーションプログラムのために予約されているインデックス範囲の下限を指定します。
- SHT_HIUSER
- この値は、アプリケーションプログラムのために予約されているインデックス範囲の上限を指定します。 SHT_LOUSER と SHT_HIUSER の間のセクションタイプは、アプリケーションによって使用可能であり、現在または将来のシステム定義セクションタイプと衝突しません。
- sh_flags
-
セクションは、雑多な属性を記述する 1 ビットフラグをサポートします。フラグビットが
sh_flags でセットされるならば、そのセクションの属性は“オン”になります。そうでなければ、属性は“オフ”であるか、あてはまりません。未定義属性は、0 にセットされます。
- SHF_WRITE
- セクションは、プロセス実行の間、書き込み可能であるべきデータを含みます。
- SHF_ALLOC
- セクションは、プロセス実行の間、メモリを占有します。制御セクションには、オブジェクトファイルのメモリイメージで存在しないものがあります。そのようなセクションでは、この属性はオフです。
- SHF_EXECINSTR
- セクションは、実行可能な機械語命令を含みます。
- SHF_MASKPROC
- このマスクで含まれる全てのビットは、プロセッサ固有のセマンティクスのために確保されます。
- sh_addr
- セクションがプロセスのメモリイメージに現れる場合、このメンバは、セクションの最初のバイトが存在するアドレスを持ちます。そうでない場合、このメンバは 0 を含みます。
- sh_offset
- このメンバ値は、このセクションの、ファイル先頭からのバイトオフセットを与えます。 1 つのセクションタイプ、すなわち SHT_NOBITS は、ファイル中の空間を占有せず、その sh_offset メンバは、ファイル中の概念上の位置を指定します。
- sh_size
- このメンバは、セクションのバイトでの大きさを持ちます。セクションタイプが SHT_NOBITS でない限り、セクションはファイル中の sh_size バイトを占有します。タイプ SHT_NOBITS のセクションは 0 以外の大きさを持ち得ますが、ファイル中の空間を占有しません。
- sh_link
- このメンバは、セクションヘッダテーブルインデックスリンクを持ちます。この解釈は、セクションタイプ依存です。
- sh_info
- このメンバは、追加情報を持ちます。この解釈は、セクションタイプ依存です。
- sh_addralign
- 若干のセクションには、アドレス境界の制約があります。セクションがダブルワードを持つならば、システムはダブルワード境界をセクション全体に保証する必要があります。 sh_addr の値は、 sh_addralign で割った値が 0 となることが必要です。 0 と正の 2 の羃乗だけが許されます。 0 または 1 の値は、セクションには境界の制約がないことを意味します。
- sh_entsize
- 若干のセクションは、固定長エントリのテーブルを持ちます。例えばシンボルテーブルがこれに該当します。そのようなセクションのために、このメンバは、各エントリのバイトでの大きさを与えます。セクションが固定サイズのエントリのテーブルを持たないならば、このメンバは 0 を含みます。
様々なセクションが、プログラムと制御情報を持ちます:
- .bss
- (シンボルで始まっているブロック) このセクションは初期化されないデータを持ち、プログラムのメモリイメージになります。定義では、プログラム開始時にシステムがデータを 0 初期化します。このセクションは、タイプ SHT_NOBITS です。属性タイプは、 SHF_ALLOC と SHF_WRITE です。
- .comment
- このセクションは、バージョン制御情報を持ちます。このセクションは、タイプ SHT_PROGBITS です。属性タイプは使われません。
- .data
- このセクションは初期化されたデータを持ち、プログラムのメモリイメージになります。このセクションは、タイプ SHT_PROGBITS です。属性タイプは、 SHF_ALLOC と SHF_WRITE です。
- .data1
- このセクションは初期化されたデータを持ち、プログラムのメモリイメージになります。このセクションは、タイプ SHT_PROGBITS です。属性タイプは、 SHF_ALLOC と SHF_WRITE です。
- .debug
- このセクションは、シンボリックデバッギングのための情報を持ちます。内容は、明記されていません。このセクションは、タイプ SHT_PROGBITS です。属性タイプは使われません。
- .dynamic
- このセクションは、動的リンク情報を持ちます。セクションの属性は、 SHF_ALLOC ビットを含みます。 SHF_WRITE ビットがセットされるか否かは、プロセッサ依存です。このセクションは、タイプ SHT_DYNAMIC です。上の属性を見てください。
- .dynstr
- このセクションは、動的リンクのために必要とされる文字列を持ちます。そして一般には、名前を表現する文字列であり、シンボルテーブルエントリと結び付けられています。このセクションは、タイプ SHT_STRTAB です。使われる属性タイプは、 SHF_ALLOC です。
- .dynsym
- このセクションは、動的リンクシンボルテーブルを持ちます。このセクションは、タイプ SHT_DYNSYM です。使われる属性は、 SHF_ALLOC です。
- .fini
- このセクションは、プロセス終了コードの実行可能命令を持ちます。プログラムの正常終了時に、システムはこのセクションのコードを実行します。このセクションは、タイプ SHT_PROGBITS です。使われる属性は、 SHF_ALLOC と SHF_EXECINSTR です。
- .got
- このセクションは、グローバルオフセットテーブルを持ちます。このセクションは、タイプ SHT_PROGBITS です。属性は、プロセッサ依存です。
- .hash
- このセクションは、シンボルハッシュテーブルを持ちます。このセクションは、タイプ SHT_HASH です。使われる属性は、 SHF_ALLOC です。
- .init
- このセクションは、プロセス初期化コードの実行可能命令を持ちます。プログラム実行開始時に、メインプログラムエントリポイントを呼び出す前に、システムはこのセクションのコードを実行します。このセクションは、タイプ SHT_PROGBITS です。使われる属性は、 SHF_ALLOC と SHF_EXECINSTR です。
- .interp
- このセクションは、プログラムインタプリタのパス名を持ちます。ファイルがこのセクションを含むロード可能なセグメントを持つならば、セクションの属性は SHF_ALLOC ビットを含みます。そうでない場合、このビットはオフです。このセクションは、タイプ SHT_PROGBITS です。
- .line
- このセクションはシンボリックデバッギングのために行番号情報を持ちます。これは、プログラムソースとマシンコードの間の関係を記述します。内容は、明記されていません。このセクションは、タイプ SHT_PROGBITS です。属性タイプは使われません。
- .note
- このセクションは、下で記述される“Note Section”フォーマットで、情報を持ちます。このセクションは、タイプ SHT_NOTE です。属性タイプは使われません。
- .plt
- このセクションは、プロシージャリンケージテーブルを持ちます。このセクションは、タイプ SHT_PROGBITS です。属性はプロセッサ依存です。
- .relNAME
- このセクションは、下記のように再配置情報を持ちます。ファイルが再配置を含むロード可能なセグメントを持つならば、セクションの属性は SHF_ALLOC ビットを含みます。そうでない場合、このビットはオフです。規約により、再配置されるセクションから“NAME”が与えられます。 .text のための再配置セクションは、通常名前 .rel.text を持ちます。このセクションは、タイプ SHT_REL です。
- .relaNAME
- このセクションは、下記のように再配置情報を持ちます。ファイルが再配置を含むロード可能なセグメントを持つならば、セクションの属性は SHF_ALLOC ビットを含みます。そうでない場合、このビットはオフです。規約により、再配置されるセクションから“NAME”が与えられます。 .text のための再配置セクションは、通常名前 .rela.text を持ちます。このセクションは、タイプ SHT_RELA です。
- .rodata
- このセクションは読み込み専用データを持ち、典型的にはプロセスイメージの書き込み不可セグメントになります。このセクションは、タイプ SHT_PROGBITS です。使われる属性は、 SHF_ALLOC です。
- .rodata1
- このセクションは読み込み専用データを持ち、典型的にはプロセスイメージの書き込み不可セグメントになります。このセクションは、タイプ SHT_PROGBITS です。使われる属性は、 SHF_ALLOC です。
- .shstrtab
- このセクションはセクション名を持ちます。このセクションは、タイプ SHT_STRTAB です。属性タイプは使われません。
- .strtab
- このセクションは文字列を持ちます。一般的には名前を表示する文字列であり、シンボルテーブルエントリと結び付けられています。ファイルがシンボル文字列テーブルを含むロード可能なセグメントを持つならば、セクションの属性は SHF_ALLOC ビットを含みます。そうでない場合、このビットはオフです。このセクションは、タイプ SHT_STRTAB です。
- .symtab
- このセクションは、シンボルテーブルを持ちます。ファイルがシンボルテーブルを含むロード可能なセグメントを持つならば、セクションの属性は SHF_ALLOC ビットを含みます。そうでない場合、このビットはオフです。このセクションは、タイプ SHT_SYMTAB です。
- .text
- このセクションは、プログラムの“テキスト”、すなわち実行可能命令を持ちます。このセクションは、タイプ SHT_PROGBITS です。使われる属性は、 SHF_ALLOC と SHF_EXECINSTR です。
- .jcr
- このセクションは、登録される必要がある Java クラスの情報を持ちます。
- .eh_frame
- このセクションは、C++ 例外処理に使用される情報を持ちます。
文字列テーブルセクションは、ヌル文字で終わる文字シーケンス群を持ちます。これらは、一般に文字列と呼ばれます。オブジェクトファイルは、シンボルとセクション名を表現するためにこれらの文字列を使います。文字列テーブルセクションのインデックスとして、文字列を参照します。最初のバイト (インデックス 0) は、単一のヌル文字を持つと定義されます。同様に、文字列テーブルの最終バイトはヌル文字であると定義されので、文字列全体がナル終端されていることを保証します。
オブジェクトファイルのシンボルテーブルは、プログラムのシンボル定義と参照の位置決定に必要な情報を保持します。シンボルテーブルインデックスは、この配列の添字です。
typedef struct { Elf32_Word st_name; Elf32_Addr st_value; Elf32_Word st_size; unsigned char st_info; unsigned char st_other; Elf32_Half st_shndx; } Elf32_Sym;
typedef struct { Elf64_Word st_name; unsigned char st_info; unsigned char st_other; Elf64_Half st_shndx; Elf64_Addr st_value; Elf64_Xword st_size; } Elf64_Sym;
- st_name
- このメンバは、オブジェクトファイルのシンボル文字列テーブルへのインデックスを持ちます。シンボル文字列テーブルは、シンボル名の文字表現を持ちます。値が 0 以外であるならば、それはシンボル名を与える文字列テーブルインデックスを示します。そうでない場合、シンボルテーブルには名前がありません。
- st_value
- このメンバは、関連したシンボルの値を与えます。
- st_size
- 多くのシンボルは、関連した大きさを持ちます。シンボルには大きさが無いか未知である場合、このメンバは 0 です。
- st_info
-
このメンバは、シンボルのタイプと束縛属性を指定します:
- STT_NOTYPE
- シンボルのタイプは、定義されません。
- STT_OBJECT
- シンボルは、データオブジェクトと結び付けられています。
- STT_FUNC
- シンボルは、関数または他の実行可能コードと結び付けられています。
- STT_SECTION
- シンボルは、セクションと結び付けられています。このタイプのシンボルテーブルエントリは、主に再配置のために存在して、通常 STB_LOCAL 束縛を持ちます。
- STT_FILE
- 規約により、シンボルの名前は、オブジェクトファイルと関連するソースファイルの名前を与えます。存在する場合、ファイルシンボルは STB_LOCAL 束縛を持ち、そのセクションインデックスは SHN_ABS であり、それはファイルの他の STB_LOCAL シンボルに先行します。
- STT_LOPROC
- この値から STT_HIPROC 以下は、プロセッサに固有のセマンティクスのために予約されています。
- STT_HIPROC
- この値から STT_LOPROC 以上は、プロセッサに固有のセマンティクスのために予約されています。
- STB_LOCAL
- ローカルなシンボルは、それらの定義を含んでいるオブジェクトファイルの外側には、見えません。同じ名前のローカルなシンボルは、お互いのじゃまをすることなく複数ファイルで存在し得ます。
- STB_GLOBAL
- グローバルシンボルは、結合されている全てのオブジェクトファイルから見えます。あるファイルによるグローバルシンボルの定義は、別ファイルの同じシンボルの未定義参照を満足させます。
- STB_WEAK
- 弱いシンボルはグローバルシンボルに似ています。しかし、彼らの定義は低い優先順位を持ちます。
- STB_LOPROC
- この値から STB_HIPROC 以下は、プロセッサに固有のセマンティクスのために予約されています。
- STB_HIPROC
-
この値から
STB_LOPROC 以上は、プロセッサに固有のセマンティクスのために予約されています。
束縛とタイプフィールドのパックおよびアンパック用のマクロがあります:
- ELF32_ST_BIND( info)
- または ELF64_ST_BIND( info) は、束縛を st_info 値から引出します。
- ELF64_ST_TYPE( info)
- または ELF32_ST_TYPE( info) は、タイプを st_info 値から引出します。
- ELF32_ST_INFO( bind, type)
- または ELF64_ST_INFO( bind, type) は、束縛とタイプを st_info 値へ変換します。
- st_other
- このメンバは、現在 0 を持ち、定義された意味を持ちません。
- st_shndx
- あらゆるシンボルテーブルエントリは、なんらかのセクションに関して“定義されています”。このメンバは、関連するセクションヘッダテーブルインデックスを持ちます。
再配置は、シンボル参照とシンボル定義を接続する処理です。再配置可能なファイルは、それらのセクション内容の修正方法を記述する情報を持つ必要があります。このようにして、実行可能ファイルと共有オブジェクトファイルが、プロセスのプログラムイメージのための正しい情報を持てます。再配置エントリは、これらのデータです。
加数を必要としない再配置構造体:
typedef struct { Elf32_Addr r_offset; Elf32_Word r_info; } Elf32_Rel;
typedef struct { Elf64_Addr r_offset; Elf64_Xword r_info; } Elf64_Rel;
加数を必要とする再配置構造体:
typedef struct { Elf32_Addr r_offset; Elf32_Word r_info; Elf32_Sword r_addend; } Elf32_Rela;
typedef struct { Elf64_Addr r_offset; Elf64_Xword r_info; Elf64_Sxword r_addend; } Elf64_Rela;
- r_offset
- このメンバは、再配置動作を適用する場所を与えます。再配置可能なファイルでは、値は、再配置によって影響を受ける記憶単位のセクション先頭からのバイトオフセットです。実行可能ファイルまたは共用オブジェクトでは、値は、再配置によって影響を受ける記憶単位の仮想アドレスです。
- r_info
- このメンバは、再配置されるシンボルテーブルインデックスと、使用する再配置のタイプを与えます。再配置タイプは、プロセッサ依存です。テキストが再配置エントリの再配置タイプまたはシンボルテーブルインデックスを参照するとき、エントリの r_info メンバに対し、それぞれ ELF_[32|64]_R_TYPE または ELF[32|64]_R_SYM を適用する結果を意味しています。
- r_addend
- このメンバは、定数の加数を指定します。これは、再配置可能なフィールドに格納される値を計算するために使用されます。
関連項目
as(1), gdb(1), ld(1), objdump(1), execve(2), ar(5), core(5) Hewlett Packard, Elf-64 Object File Format. Santa Cruz Operation, System V Application Binary Interface. Unix System Laboratories, Object Files, Executable and Linking Format (ELF).歴史
ELF ヘッダファイルは、 FreeBSD 2.2.6 で登場しました。 ELF 自体は、 AT&T System V UNIX ではじめて登場しました。 ELF フォーマットは、標準として採用されています。December 18, 2005 | FreeBSD |