ELF(5)

名称
elf - ELF 実行形式バイナリファイルのフォーマット

書式
<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_NIDENTT
        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 を持ちます。

    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 の間であり、両端を含みます。 これらの値は、セクションヘッダテーブルを参照しません。 セクションヘッダテーブルは予約のインデックスのためにエントリを 含みません。

実行可能ファイルまたは共有オブジェクトファイルのプログラムヘッダテーブルは、 構造体の配列です。 各構造体は、 プログラム実行にシステムが必要とする、セグメント等の情報を記述します。 オブジェクトファイルの セグメント は、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_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, Object Files, Executable and Linking Format (ELF).

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

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