ELF(5) | Linux Programmer's Manual | ELF(5) |
名前¶
elf - 実行可能リンクフォーマット (ELF) ファイルのフォーマット
書式¶
#include <elf.h>
説明¶
ヘッダファイル <elf.h> は ELF 実行可能バイナリファイルのフォーマットを定義する。 これらのファイルとしては、通常の実行可能ファイル・ 再配置可能オブジェクトファイル・コアファイル・共有ライブラリがある。
ELF ファイルフォーマットを使う実行可能ファイルは、 ELF ヘッダの後にプログラムヘッダテーブルまたは セクションヘッダテーブル (またはその両方) が続く構成である。 ELF ヘッダは常にファイルのオフセット 0 にある。 プログラムヘッダテーブルとセクションヘッダテーブルの ファイル内でのオフセットは、ELF ヘッダに定義されている。 この 2 つのテーブルはファイルの残りの部分の詳細を記述する。
このヘッダファイルは上記のヘッダを C 言語の構造体で記述し、 また動的セクション・再配置可能セクション・シンボルテーブルの構造体も 含んでいる。
以下の型は N
ビットアーキテクチャで使われる
(N=32,64 であり ElfN は Elf32
または Elf64 を表し、
uintN_t は uint32_t または
uint64_t を表す):
ElfN_Addr 符号なしのプログラムアドレス, uintN_t ElfN_Off 符号なしのファイルオフセット, uintN_t ElfN_Section 符号なしのセクションインデックス, uint16_t ElfN_Versym 符号なしのバージョンシンボル情報, uint16_t Elf_Byte unsigned char ElfN_Half uint16_t ElfN_Sword int32_t ElfN_Word uint32_t ElfN_Sxword int64_t ElfN_Xword uint64_t
(注意: *BSD での用語は少し異なる。 Elf64_Half は Elf32_Half の 2 倍であり、 Elf64Quarter が uint16_t に用いられる。 混乱を避けるため、以下では、これらの型はサイズが自明な型に置き換えてある。)
このファイルフォーマットが定義する全てのデータ構造体は、 関連するクラスの "自然な" サイズと配置の指針に従う。 必要な場合、データ構造体では明示的なパディング (padding, 詰め込み) が行なわれる。これは 4 バイトオブジェクトに対する 4 バイト配置を保証するためや、 構造体のサイズを 4 の倍数にするためなどである。
ELF ヘッダは型 Elf32_Ehdr
または Elf64_Ehdr
で記述される:
#define EI_NIDENT 16 typedef struct {
unsigned char e_ident[EI_NIDENT];
uint16_t e_type;
uint16_t e_machine;
uint32_t e_version;
ElfN_Addr e_entry;
ElfN_Off e_phoff;
ElfN_Off e_shoff;
uint32_t e_flags;
uint16_t e_ehsize;
uint16_t e_phentsize;
uint16_t e_phnum;
uint16_t e_shentsize;
uint16_t e_shnum;
uint16_t e_shstrndx; } ElfN_Ehdr;
フィールドは以下の意味を持つ:
- e_ident
- このバイト配列は、プロセッサやファイルの他の部分には依存せずに、 ファイルを解釈 (interpret) するために指定される。 この配列内のすべてのものは、接頭辞 EI_ で始まるマクロの名前が付き、接頭辞 ELF で始まる値を持つ。 以下のマクロが定義されている:
- EI_MAG0
- マジックナンバーの第 1 バイト。 ELFMAG0 で埋めなければならない。 (0: 0x7f)
- EI_MAG1
- マジックナンバーの第 2 バイト。 ELFMAG1 で埋めなければならない。 (1: 'E')
- EI_MAG2
- マジックナンバーの第 3 バイト。 ELFMAG2 で埋めなければならない。 (2: 'L')
- EI_MAG3
- マジックナンバーの第 4 バイト。 ELFMAG3 で埋めなければならない。 (3: 'F')
- 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_NONE
- ELFOSABI_SYSV と同じ。
- ELFOSABI_SYSV
- UNIX System V ABI.
- ELFOSABI_HPUX
- HP-UX ABI.
- ELFOSABI_NETBSD
- NetBSD ABI.
- ELFOSABI_LINUX
- Linux ABI.
- ELFOSABI_SOLARIS
- Solaris ABI.
- ELFOSABI_IRIX
- IRIX ABI.
- ELFOSABI_FREEBSD
- FreeBSD ABI.
- ELFOSABI_TRU64
- TRU64 UNIX ABI.
- ELFOSABI_ARM
- ARM アーキテクチャ ABI.
- ELFOSABI_STANDALONE
- スタンドアロン (組み込み) ABI.
- EI_ABIVERSION
- このバイトはオブジェクトがターゲットとしている ABI のバージョンを示す。 このフィールドは互換性のない ABI のバージョンを区別するために使われる。 このバージョン番号の解釈は、 EI_OSABI フィールドで識別される ABI に依存する。 この仕様に準拠するアプリケーションは、値 0 を使う。
- EI_PAD
- パディングの開始。 これらのバイトは予約されており、0 に設定されている。 これらを読み込むプログラムは、これらのバイトを無視すべきである。 現在使われていないバイトに意味が与えられる場合、 EI_PAD の値は将来変更されるかもしれない。
- EI_BRAND
- アーキテクチャ ID の開始。
- EI_NIDENT
- e_ident 配列のサイズ。
- e_type
- この構造体のメンバはオブジェクトファイルタイプを示す:
- 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_860
- Intel 80860.
- EM_MIPS
- MIPS RS3000 (ビッグエンディアンのみ)。
- EM_PARISC
- HP/PA.
- EM_SPARC32PLUS
- 拡張命令セット付き SPARC。
- EM_PPC
- PowerPC.
- EM_PPC64
- PowerPC 64-bit.
- EM_S390
- IBM S/390
- EM_ARM
- Advanced RISC Machines
- EM_SH
- Renesas SuperH
- EM_SPARCV9
- SPARC v9 64-bit.
- EM_IA_64
- Intel Itanium
- EM_X86_64
- AMD x86-64
- EM_VAX
- DEC Vax.
- e_version
- このメンバはファイルバージョンを示す:
- EV_NONE
- 不正なバージョン。
- EV_CURRENT
- 現在のバージョン。
- e_entry
- このメンバは、システムが最初に制御を渡す、 つまりプロセスを開始する仮想アドレスを指定する。 ファイルにエントリポイントが関連付けられていない場合、 このメンバには 0 が入る。
- e_phoff
- このメンバはプログラムヘッダテーブルの ファイルオフセット (バイト単位) を保持する。 ファイルにプログラムヘッダテーブルがない場合、 このメンバには 0 が入る。
- 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_UNDEF に関連づけて「定義」されたシンボルは、「未定義」なシンボルである。
- SHN_LORESERVE
- この値は予約済みのインデックス範囲の下限を指定する。
- SHN_LOPROC
- この値以上で SHN_HIPROC 以下の値は、プロセッサ固有の意味に予約されている。
- SHN_HIPROC
- この値以下で SHN_LOPROC 以上の値は、プロセッサ固有の意味に予約されている。
- SHN_ABS
- この値は対応する参照の絶対値を指定する。 例えば、セクション番号 SHN_ABS に関連づけられたシンボルは絶対値を保持し、再配置に影響されない。
- SHN_COMMON
- このセクションに関連して定義されたシンボルは、 Fortran の COMMON や C の未割り当て external 変数のような、 共通シンボルである。
- SHN_HIRESERVE
- この値は予約されたインデックスの範囲の上限を指定する。 SHN_LORESERVE と SHN_HIRESERVE は含まれる。 この値はセクションヘッダテーブルを参照しない。 つまり、セクションヘッダテーブルは 予約されたインデックスのエントリを 含まない 。
実行可能ファイルまたは共有オブジェクトファイルのプログラムヘッダテーブルは、
システムによるプログラム実行準備に必要な、
セグメント等の情報を記述する構造体の配列である。
オブジェクトファイルの
セグメント には 1
つ以上の
セクション
が含まれる。
プログラムヘッダは実行可能ファイルと共有オブジェクトファイルでのみ意味を持つ。
ファイルは自身のプログラムヘッダサイズを
ELF ヘッダの e_phentsize
メンバと e_phnum
メンバで指定する。 ELF
プログラムヘッダは
Elf32_Phdr 型または Elf64_Phdr
型で記述される
(どちらになるかはアーキテクチャ依存):
typedef struct {
uint32_t p_type;
Elf32_Off p_offset;
Elf32_Addr p_vaddr;
Elf32_Addr p_paddr;
uint32_t p_filesz;
uint32_t p_memsz;
uint32_t p_flags;
uint32_t p_align; } Elf32_Phdr;
typedef struct {
uint32_t p_type;
uint32_t p_flags;
Elf64_Off p_offset;
Elf64_Addr p_vaddr;
Elf64_Addr p_paddr;
uint64_t p_filesz;
uint64_t p_memsz;
uint64_t p_align; } Elf64_Phdr;
32 ビットと 64 ビットのプログラムヘッダの主な違いは、構造体における p_flags メンバの位置にある。
- p_type
- Phdr 構造体のこのメンバは、 この配列要素がどのような種類のセグメントを記述しているか、 またはこの配列要素の情報をどのように解釈するか、を表す。
- PT_NULL
- この配列要素は使用されておらず、その他のメンバの値は未定義である。 これにより、このプログラムヘッダのエントリは無視される。
- PT_LOAD
- この配列要素は p_filesz と p_memsz で記述されるロード可能セグメントを指定する。 このファイルからのバイトデータが、このメモリセグメントの先頭からマップされる。 セグメントのメモリサイズ Syp_memsz がファイルサイズ Syp_filesz より大きい場合、 「余った」バイトは値 0 となり、 そのセグメント初期化データの後ろに置かれると定められている。 ファイルサイズはメモリサイズより大きくてはいけない。 プログラムヘッダテーブルのロード可能セグメントエントリは、 p_vaddr メンバの昇順にソートされて出現する。
- PT_DYNAMIC
- この配列要素は動的リンク情報を指定する。
- PT_INTERP
- この配列要素は、インタプリタとして起動されるパス名 (NULL 文字終端) の位置とサイズを指定する。 このセグメント型は (共有オブジェクトにもあるかも知れないが) 実行可能ファイルでのみ意味を持つ。 ただし、このセグメント型は 1 つのファイルに 2 回以上出現してはならない。 もし存在する場合、このセグメント型は 全てのロード可能セグメントエントリより前になければならない。
- PT_NOTE
- この配列要素は補足情報 (auxiliary information) の位置とサイズを指定する。
- PT_SHLIB
- このセグメント型は予約されているが、意味は指定されていない。 この型の配列要素を保持するプログラムは ABI に準拠しない。
- PT_PHDR
- この配列要素は、もし存在しているならば、 ファイルおよびプログラムのメモリイメージ双方における プログラムヘッダテーブル自身の位置とサイズを指定する。 このセグメント型は 1 つのファイルに 2 回以上出現してはならない。 さらに、このセグメント型が存在してもよいのは、プログラムヘッダテーブルが プログラムのメモリイメージの一部である場合のみである。 もし存在する場合、これは全てのロード可能セグメントエントリより 前になければならない。
- PT_LOPROC
- この値以上で PT_HIPROC 以下の値はプロセッサ固有の意味に予約されている。
- PT_HIPROC
- この値以下で PT_LOPROC 以上の値はプロセッサ固有の意味に予約されている。
- PT_GNU_STACK
- GNU 拡張であり、Linux カーネルが p_flags のメンバーにセットされたフラグ経由でスタックの状態を制御するために使用する。
- p_offset
- このメンバは、セグメントの先頭バイトがある (ファイル先頭からの) オフセットを保持する。
- p_vaddr
- このメンバは、セグメントの先頭バイトがある メモリの仮想アドレスを保持する。
- p_paddr
- 物理アドレスが意味をもつシステムでは、 このメンバはセグメントの物理アドレスとして予約されている。 BSD ではこのメンバは使用されない。0 でなければならない。
- p_filesz
- このメンバはセグメントのファイルイメージのバイト数を保持する。 これは 0 でもよい。
- p_memsz
- このメンバはセグメントのメモリイメージのバイト数を保持する。 これは 0 でもよい。
- p_flags
- このメンバはセグメントに関連するフラグのビットマップを保持する:
- テキストセグメントは一般にフラグ PF_X と PF_R を持つ。 データセグメントは一般に PF_X, PF_W, PF_R を持つ。
- p_align
- このメンバは、セグメントがメモリおよびファイルにおいて配置 (align) される値を保持する。 ロード可能プロセスセグメントは、ページサイズを法として p_vaddr と p_offset と合同でなければならない (訳注:「p_vaddr mod ページサイズ = p_offset mod ページサイズ」 でなければならない)。。 0 と 1 という値は配置が必要ないことを意味する。 それ以外の場合、 p_align は正で 2 の整数乗でなければならず、 p_vaddr は p_align を法として p_offset と合同でなければならない (訳注:「p_vaddr mod p_align = p_offset mod p_align」でなければならない)。
ファイルのセクションヘッダテーブルには、 全てのファイルセクションの場所が記述されている。 セクションヘッダテーブルは Elf32_Shdr 構造体または Elf64_Shdr 構造体の配列である。 ELF ヘッダの e_shoff メンバはファイルの先頭から セクションヘッダテーブルへのバイトオフセットである。 e_shnum はセクションヘッダテーブルに含まれるエントリの数を保持する。 e_shentsize は各エントリのサイズ (バイト単位) を保持する。
セクションヘッダテーブルインデックスは、この配列の要素を指定する。 いくつかのセクションヘッダテーブルインデックスは予約されている。 オブジェクトファイルは、これらの特別なインデックスに対応する セクションを持たない:
- SHN_UNDEF
- この値は未定義・不明・無関係・無意味なセクション参照の印となる。
- SHN_LORESERVE
- この値は予約済みのインデックス領域の下限を指定する。
- SHN_LOPROC
- この値以上で SHN_HIPROC 以下の値はプロセッサ固有の意味に予約されている。
- SHN_HIPROC
- この値以下で SHN_HIPROC 以上の値はプロセッサ固有の意味に予約されている。
- SHN_ABS
- この値は対応する参照の絶対値を指定する。 例えば、セクション番号 SHN_ABS に関連して定義されているシンボルは、 絶対値を保持しているので、再配置に影響されない。
- SHN_COMMON
- このセクションに関連して定義されているシンボルは、 FORTRAN の COMMON や C の未割り当て外部変数のような共通シンボルである。
- SHN_HIRESERVE
- この値は予約済みのインデックス領域の上限を指定する。 システムは SHN_LORESERVE と SHN_HIRESERVE を含む範囲を予約する。 セクションヘッダテーブルは予約されたインデックスに対応するエントリを持たない。
セクションヘッダは以下の構造体を持つ:
typedef struct {
uint32_t sh_name;
uint32_t sh_type;
uint32_t sh_flags;
Elf32_Addr sh_addr;
Elf32_Off sh_offset;
uint32_t sh_size;
uint32_t sh_link;
uint32_t sh_info;
uint32_t sh_addralign;
uint32_t sh_entsize; } Elf32_Shdr;
typedef struct {
uint32_t sh_name;
uint32_t sh_type;
uint64_t sh_flags;
Elf64_Addr sh_addr;
Elf64_Off sh_offset;
uint64_t sh_size;
uint32_t sh_link;
uint32_t sh_info;
uint64_t sh_addralign;
uint64_t sh_entsize; } Elf64_Shdr;
32 ビットと 64 ビットのセクションヘッダには実際の違いはない。
- sh_name
- このメンバはセクション名を定める。 この値はセクションヘッダ文字列テーブルセクションのインデックスであり、 NULL 文字で終端された文字列の場所を示す。
- sh_type
- このメンバはセクションの内容と意味が含まれるカテゴリを示す。
- SHT_NULL
- この値はセクションヘッダが不活性であることを示す。 これは関連するセクションを持たない。 このセクションヘッダの他のメンバは、未定義の値を持つ。
- SHT_PROGBITS
- このセクションはプログラムにより定義される情報を保持する。 この情報の形式と意味は、ひとえにプログラムによって決定される。
- SHT_SYMTAB
- このセクションはシンボルテーブルを保持する。 一般には SHT_SYMTAB はリンク編集のためのシンボルを提供するが、 動的リンクにも使われる。 完全なシンボルテーブルとして、動的リンクには不要な 多くのシンボルを保持できる。 オブジェクトファイルも SHT_DYNSYM セクションを持つことができる。
- SHT_STRTAB
- このセクションは文字列テーブルを保持する。 オブジェクトファイルは複数の文字列テーブルセクションを持つことができる。
- SHT_RELA
- このセクションは明示的な加数 (addend) を持つ再配置エントリを保持する。 再配置エントリの型は、オブジェクトファイルの 32 ビットクラスでは Elf32_Rela である。 オブジェクトファイルは複数の再配置セクションを持つことができる。
- SHT_HASH
- このセクションはシンボルハッシュテーブルを保持する。 動的リンクされるオブジェクトは、 シンボルハッシュテーブルを含んでいなければならない。 オブジェクトファイルは 1 つのハッシュテーブルのみを持つことができる。
- SHT_DYNAMIC
- このセクションは動的リンクの情報を保持する。 オブジェクトファイルは 1 つの動的セクションのみを持つことができる。
- SHT_NOTE
- このセクションはファイルに何らかの印を付ける情報を保持する。
- SHT_NOBITS
- このタイプのセクションはファイルの領域を使わないという以外は、 SHT_PROGBITS と似ている。 このセクションは 1 バイトも含まないが、 sh_offset メンバは概念的なファイルオフセットを持つ。
- SHT_REL
- このセクションは明示的な加数を持たない再配置オフセットを保持する。 再配置オフセットの型は、オブジェクトファイルの 32 ビットクラスでは Elf32_Rel である。 オブジェクトファイルは複数の再配置セクションを持つことができる。
- SHT_SHLIB
- このセクションは予約されているが、意味は指定されていない。
- SHT_DYNSYM
- このセクションは動的リンクシンボルの最小セットを保持する。 オブジェクトファイルは SHT_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
- このメンバの値は、ファイルの先頭からセクションの最初のバイトへの バイトオフセットを保持する。 セクションタイプ SHT_NOBITS はファイルの領域を全く使用せず、このタイプの sh_offset メンバはファイルの概念的な位置を示す。
- sh_size
- このメンバはセクションのサイズ (バイト単位) を保持する。 セクションタイプが SHT_NOBITS でない限り、そのセクションはファイル中の sh_size バイトを使用する。 タイプが SHT_NOBITS のセクションはサイズが 0 でないが、ファイルの領域を使用しない。
- sh_link
- このメンバは、セクションヘッダテーブルインデックスリンクを保持する。 この解釈はセクションタイプに依存する。
- sh_info
- このメンバは追加情報を保持する。 この解釈はセクションタイプに依存する。
- sh_addralign
- アドレス配置に制約があるセクションもある。 セクションが倍長語 (doubleword) を保持する場合、 システムは全てのセクションについて倍長語の配置を保証しなければならない。 つまり、 sh_addr の値は sh_addralign の値を法として 0 と合同でなければならない (訳注:「sh_addr mod sh_addralign = 0 でなければならない)。 2 の 0 乗と正の整数乗のみが許可される。 0 または 1 はセクションの配置に制約がないことを意味する。
- sh_entsize
- シンボルテーブルのような固定サイズエントリのテーブルを保持する セクションもある。 このようなセクションでは、 このメンバは各エントリのサイズ (バイト単位) を表す。 このメンバが 0 の場合、 そのセクションは固定サイズエントリのテーブルを保持しない。
さまざまなセクションにプログラム情報・制御情報が保持される:
- .bss
- このセクションはプログラムのメモリイメージに配置される 非初期化データを保持する。 定義上、システムはプログラムの実行開始時に、データを 0 で初期化する。 このセクションのタイプは SHT_NOBITS である。 属性タイプは SHF_ALLOC と SHF_WRITE である。
- .comment
- このセクションはバージョン制御情報を保持する。 このセクションのタイプは SHT_PROGBITS である。 属性タイプは使用されない。
- .ctors
- このセクションは C++ コンストラクタ関数への初期化されたポインタを保持する。 このセクションのタイプは SHT_PROGBITS である。 属性タイプは SHF_ALLOC と SHF_WRITE である。
- .data
- このセクションはプログラムのメモリイメージに配置される 初期化済みデータを保持する。 このセクションのタイプは SHT_PROGBITS である。 属性タイプは SHF_ALLOC と SHF_WRITE である。
- .data1
- このセクションはプログラムのメモリイメージに配置される 初期化済みデータを保持する。 このセクションのタイプは SHT_PROGBITS である。 属性タイプは SHF_ALLOC と SHF_WRITE である。
- .debug
- このセクションはシンボリックデバッグ用の情報を保持する。 その内容は指定されていない。 このセクションのタイプは SHT_PROGBITS である。 属性タイプは使用されない。
- .dtors
- このセクションは C++ デストラクタ関数への初期化されたポインタを保持する。 このセクションのタイプは SHT_PROGBITS である。 属性タイプは SHF_ALLOC と SHF_WRITE である。
- .dynamic
- このセクションは動的リンク情報を保持する。 このセクションの属性は SHF_ALLOC ビットを含む。 SHF_WRITE ビットが設定されるか否かはプロセッサによる。 このセクションのタイプは SHT_DYNAMIC である。 上記の属性を参照すること。
- .dynstr
- このセクションは動的リンクに必要な文字列を保持する。 最も一般的には、この文字列はシンボルテーブルエントリと 関連づけられた名前を表す。 このセクションのタイプは SHT_STRTAB である。 使用される属性タイプは SHF_ALLOC である。
- .dynsym
- このセクションは動的リンクシンボルテーブルを保持する。 このセクションのタイプは SHT_DYNSYM である。 使用される属性タイプは SHF_ALLOC である。
- .fini
- このセクションはプロセス終了コードに置かれる実行可能命令を保持する。 プロセスが正常に終了した場合、システムはこのセクションにある コードを配置して実行する。 このセクションのタイプは SHT_PROGBITS である。 使用される属性タイプは SHF_ALLOC と SHF_EXECINSTR である。
- .gnu.version
- このセクションはバージョン・シンボル・テーブルを保持する。 その内容は ElfN_Half 要素の配列である。 このセクションのタイプは SHT_GNU_versym である。 使用される属性タイプは SHF_ALLOC である。
- .gnu.version_d
- このセクションはバージョンシンボルの定義を保持する。 その内容は ElfN_Verdef 構造体のテーブルである。 このセクションのタイプは SHT_GNU_verdef である。 使用される属性タイプは SHF_ALLOC である。
- .gnu.version_r
- このセクションはバージョンシンボルが必要とする要素を保持する。 その内容は ElfN_Verneed 構造体のテーブルである。 このセクションのタイプは SHT_GNU_versym である。 使用される属性タイプは shf_alloc である。
- .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 である。 属性タイプは使用されない。 通常 OpenBSD ネイティブ実行可能ファイルは自身を識別するために .note.openbsd.ident セクションを持つ。 これによりカーネルは、ファイルをロードする際に 互換 ELF バイナリエミュレーションテストを回避できる。
- .note.GNU-stack
- このセクションは Linux のオブジェクトファイルで スタック属性を宣言するのに使用される。 セクションのタイプは SHT_PROGBITS である。使用される属性は SHF_EXECINSTR だけである。この属性は GNU リンカに対して オブジェクトファイルが実行可能なスタック (executable stack) を必要とする 示すものである。
- .plt
- このセクションは手続き (procedure) リンクテーブルを保持する。 このセクションのタイプは 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 である。
文字列テーブルセクションは NULL 文字で終端されたキャラクタ配列 (通常文字列と呼ばれるもの) を保持する。 オブジェクトファイルはこれらの文字列を シンボル名とセクション名を表すために使う。 文字列は、文字列テーブルセクションへのインデックスとして参照される。 インデックス 0 の最初のバイトは、NULL バイト ('\0') を 保持すると定義されている。 同様に文字列テーブルの最後のバイトも NULL 文字を保持すると定義されている。 これは全ての文字列が NULL バイトで終端されていることを保証するためである。
オブジェクトファイルのシンボルテーブルは、
プログラムのシンボル定義と参照を配置または再配置するのに
必要な情報を保持する。
typedef struct {
uint32_t st_name;
Elf32_Addr st_value;
uint32_t st_size;
unsigned char st_info;
unsigned char st_other;
uint16_t st_shndx; } Elf32_Sym;
typedef struct {
uint32_t st_name;
unsigned char st_info;
unsigned char st_other;
uint16_t st_shndx;
Elf64_Addr st_value;
uint64_t st_size; } Elf64_Sym;
32 ビット版と 64 ビット版は同じメンバを持ち、単に順番が異なるだけである。
- st_name
- このメンバはオブジェクトファイルのシンボル文字列テーブルの インデックスを保持する。 シンボル文字列テーブルはシンボル名の文字表現を保持する。 この値が 0 でない場合、シンボル名を得るための文字テーブルインデックスを表す。 それ以外の場合、シンボルテーブルは名前を持たない。
- st_value
- このメンバは関連づけられたシンボルの値を表す。
- st_size
- 多くのシンボルにはそれに関連づけられたサイズがある。 シンボルがサイズを持たない場合、またはサイズが不明な場合、 このメンバは 0 である。
- st_info
- このメンバはシンボルのタイプとバインディング (binding) 属性を指定する:
- 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
- 大域的シンボルは結びつけられている全てのオブジェクトファイルから見える。 1 つのファイルで大域的シンボルが定義されていたら、 他のファイルでは同じシンボルへの参照は未定義でなければならない。
- STB_WEAK
- 弱シンボルは大域的シンボルに似ているが、その定義は優先度が低い。
- STB_LOPROC
- この値以上で STB_HIPROC 以下の範囲はプロセッサ固有の意味に予約されている。
- STB_HIPROC
- この値以下で STB_LOPROC 以上の範囲はプロセッサ固有の意味に予約されている。
- バインディングとタイプフィールドを パックしたりアンパックしたりするマクロがある:
- ELF32_ST_BIND(info) または ELF64_ST_BIND(info) st_info の値からバインディングを取り出す。
- ELF32_ST_TYPE(info) または
ELF64_ST_TYPE(info)
st_info の値からタイプを取り出す。 - ELF32_ST_INFO(bind, type) または
ELF64_ST_INFO(bind, type)
バインディングとタイプを st_info の値に変換する。
- st_other
- このメンバはシンボルの visibility (見える範囲) を規定する。
- STV_DEFAULT
- デフォルトのシンボル visibility ルール。
- STV_INTERNAL
- プロセッサ固有の隠しクラス。
- STV_HIDDEN
- シンボルは他のモジュールからは利用できない。
- STV_PROTECTED
- 横取りできず (not preemptible)、公開されない。
visibility 種別を抽出するためのマクロがある。
ELF32_ST_VISIBILITY(other) または ELF64_ST_VISIBILITY(other)
- st_shndx
- 各シンボルテーブルエントリは、いくつかのセクションに関連して "定義されている"。 このメンバは関連するセクションヘッダテーブルインデックスを保持する。
再配置はシンボル参照とシンボル定義を結合するプロセスである。 再配置可能ファイルはセクションの内容をどのように修正するかに関する 情報を持たなければならない。 これにより、実行可能ファイルと共有オブジェクトファイルは プロセスのプログラムイメージについての正しい情報を持つことができる。 再配置エントリは以下のようなデータである。
加数を必要としない再配置構造体。
typedef struct {
Elf32_Addr r_offset;
uint32_t r_info; } Elf32_Rel;
typedef struct {
Elf64_Addr r_offset;
uint64_t r_info; } Elf64_Rel;
加数を必要とする再配置構造体。
typedef struct {
Elf32_Addr r_offset;
uint32_t r_info;
int32_t r_addend; } Elf32_Rela;
typedef struct {
Elf64_Addr r_offset;
uint64_t r_info;
int64_t r_addend; } Elf64_Rela;
- r_offset
- このメンバは再配置動作が適用される位置を与える。 再配置可能ファイルの場合、この値はセクションの先頭から 再配置で影響を受ける格納単位 (storage unit) までのバイトオフセットである。 実行可能ファイルまたは共有オブジェクトの場合、 この値は再配置で影響を受ける格納単位の仮想アドレスである。
- r_info
- このメンバは、再配置が行われなければならないシンボルテーブルインデックスと、 適用される再配置のタイプの両方を与える。 再配置タイプはプロセッサ毎に異なる。 テキストが再配置エントリの再配置タイプ またはシンボルテーブルインデックスを参照している場合、 それぞれエントリの r_info メンバに対して、それぞれ ELF_[32|64]_R_TYPE と ELF[32|64]_R_SYM を適用した結果を意味する。
- r_addend
- このメンバは定数の加数を指定する。 この加数は再配置可能フィールドに格納される値を計算するために使われる。
.dynamic
セクションは、関連する動的リンク情報を保持している
一連の構造体を保持する。
d_tag メンバは d_un
の解釈を制御する。
typedef struct {
Elf32_Sword d_tag;
union {
Elf32_Word d_val;
Elf32_Addr d_ptr;
} d_un; } Elf32_Dyn; extern Elf32_Dyn _DYNAMIC[];
typedef struct {
Elf64_Sxword d_tag;
union {
Elf64_Xword d_val;
Elf64_Addr d_ptr;
} d_un; } Elf64_Dyn; extern Elf64_Dyn _DYNAMIC[];
- d_tag
- このメンバは以下の値を持つことができる:
- DT_NULL
- 動的セクションの終りのマーク
- DT_NEEDED
- 必要なライブラリの名前への文字列テーブルオフセット
- DT_PLTRELSZ
- PLT 再配置 (reloc) テーブルのサイズ (バイト単位)
- DT_PLTGOT
- PLT と GOT (または何れか一方) のアドレス
- DT_HASH
- シンボルハッシュテーブルのアドレス
- DT_STRTAB
- 文字列テーブルのアドレス
- DT_SYMTAB
- シンボルテーブルのアドレス
- DT_RELA
- Rela 再配置テーブルのアドレス
- DT_RELASZ
- Rela テーブルのサイズ (バイト単位)
- DT_RELAENT
- Rela テーブルエントリのサイズ (バイト単位)
- DT_STRSZ
- 文字列テーブルのサイズ (バイト単位)
- DT_SYMENT
- シンボルテーブルエントリのサイズ (バイト単位)
- DT_INIT
- 初期化関数のアドレス
- DT_FINI
- 終了関数のアドレス
- DT_SONAME
- 共有オブジェクトの名前への文字列テーブルオフセット
- DT_RPATH
- ライブラリ検索パスへの文字列テーブルオフセット (推奨されない)
- DT_SYMBOLIC
- リンカがシンボルの実行可能ファイルより前に この共有オブジェクトを検索した場合は、警告を出す。
- DT_REL
- Rel 再配置テーブルのアドレス
- DT_RELSZ
- Rel テーブルのサイズ (バイト単位)
- DT_RELENT
- Rel テーブルエントリのサイズ (バイト単位)
- DT_PLTREL
- PLT が参照する再配置テーブルのタイプ (Rela または Rel)
- DT_DEBUG
- デバッグのために使用されている。内容は定義されていない。
- DT_TEXTREL
- これが指定されていない場合、 書き込み不可のセグメントには再配置は適用されない。
- DT_JMPREL
- PLT 専用の再配置エントリのアドレス
- DT_BIND_NOW
- 実行可能ファイルに制御を譲る前に、 全ての再配置を処理するように動的リンカに指示する。
- DT_RUNPATH
- ライブラリ検索パスへの文字列テーブルオフセット
- DT_LOPROC
- プロセッサ固有の意味の開始
- DT_HIPROC
- プロセッサ固有の意味の終了
備考¶
ELF は System V で初めて登場した。 ELF 自体は System V で初めて登場した。 ELF フォーマットは採択された標準である。
関連項目¶
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).
2007-12-28 | Linux |