tail head cat sleep
QR code linking to this page

manページ  — ELF

名称

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      符号無しプログラムアドレス
Elf32_Half      符号無しハーフワードフィールド
Elf32_Off       符号無しファイルオフセット
Elf32_Sword     符号付き大整数
Elf32_Word      フィールドまたは符号無し大整数
Elf32_Size      符号無しオブジェクトサイズ

64 ビットアーキテクチャ用に以下のタイプが用意されています:

Elf64_Addr      符号無しプログラムアドレス
Elf64_Half      符号無しハーフワードフィールド
Elf64_Off       符号無しファイルオフセット
Elf64_Sword     符号付き大整数
Elf64_Word      フィールドまたは符号無し大整数
Elf64_Size      符号無しオブジェクトサイズ
Elf64_Quarter   符号無しクォータワードフィールド

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_Quarter   e_type;
        Elf64_Quarter   e_machine;
        Elf64_Half      e_version;
        Elf64_Addr      e_entry;
        Elf64_Off       e_phoff;
        Elf64_Off       e_shoff;
        Elf64_Half      e_flags;
        Elf64_Quarter   e_ehsize;
        Elf64_Quarter   e_phentsize;
        Elf64_Quarter   e_phnum;
        Elf64_Quarter   e_shentsize;
        Elf64_Quarter   e_shnum;
        Elf64_Quarter   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_phentsize e_phnum の積は、テーブルのバイト単位の大きさを与えます。 ファイルにプログラムヘッダがないならば、 e_phnum の値は 0 になります。
e_shentsize
  このメンバは、セクションヘッダのバイト単位の大きさを持ちます。 セクションヘッダは、 セクションヘッダテーブルの中の 1 つのエントリです; 全てのエントリは、同じ大きさです。
e_shnum このメンバは、セクションヘッダテーブル中のエントリの個数を持ちます。 つまり、 e_shentsize e_shnum の積は、セクションヘッダテーブルのバイト単位の大きさを与えます。 ファイルにセクションヘッダテーブルがないならば、 e_shnum の値は 0 になります。
e_shstrndx
  このメンバは、 セクションヘッダテーブルの、 セクション名文字列テーブルに結びつけられたエントリへの インデックスを持ちます。 ファイルにセクション名文字列テーブルがないならば、 このメンバは値 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_Size      p_filesz;
        Elf32_Size      p_memsz;
        Elf32_Word      p_flags;
        Elf32_Size      p_align;
} Elf32_Phdr;

typedef struct {
        Elf64_Half      p_type;
        Elf64_Half      p_flags;
        Elf64_Off       p_offset;
        Elf64_Addr      p_vaddr;
        Elf64_Addr      p_paddr;
        Elf64_Size      p_filesz;
        Elf64_Size      p_memsz;
        Elf64_Size      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_Size      sh_size;
        Elf32_Word      sh_link;
        Elf32_Word      sh_info;
        Elf32_Size      sh_addralign;
        Elf32_Size      sh_entsize;
} Elf32_Shdr;

typedef struct {
        Elf64_Half      sh_name;
        Elf64_Half      sh_type;
        Elf64_Size      sh_flags;
        Elf64_Addr      sh_addr;
        Elf64_Off       sh_offset;
        Elf64_Size      sh_size;
        Elf64_Half      sh_link;
        Elf64_Half      sh_info;
        Elf64_Size      sh_addralign;
        Elf64_Size      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_Size      st_size;
        unsigned char   st_info;
        unsigned char   st_other;
        Elf32_Half      st_shndx;
} Elf32_Sym;

typedef struct {
        Elf64_Half      st_name;
        unsigned char   st_info;
        unsigned char   st_other;
        Elf64_Quarter   st_shndx;
        Elf64_Addr      st_value;
        Elf64_Size      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_Size      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_Size      r_info;
        Elf64_Off       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), core(5)

Hewlett Packard, Elf-64 Object File Format,

Santa Cruz Operation, System V Application Binary Interface,

Unix System Laboratories, Executable and Linking Format (ELF), Object Files,

歴史

ELF ヘッダファイルは、 FreeBSD 2.2.6 で登場しました。 ELF 自身は、最初に AT&T V で登場しました。 ELF フォーマットは、標準として採用されています。

作者

このマニュアルページは、BSDi の
.Bsx
elf(5) のマニュアルページに触発されて、 Jeroen Ruigrok van der Werven <asmodai@FreeBSD.org> が書きました。

FreeBSD ELF (5) July 31, 1999

tail head cat sleep
QR code linking to this page


このマニュアルページサービスについてのご意見は Ben Bullock にお知らせください。 Privacy policy.

"I liken starting one's computing career with Unix, say as an undergraduate, to being born in East Africa. It is intolerably hot, your body is covered with lice and flies, you are malnourished and you suffer from numerous curable diseases. But, as far as young East Africans can tell, this is simply the natural condition and they live within it. By the time they find out differently, it is too late. They already think that the writing of shell scripts is a natural act."
— Ken Pier, Xerox PARC