EN JA
ELF(3)
ELF(3) FreeBSD Library Functions Manual ELF(3)

名称

elfELF オブジェクトを操作する API

ライブラリ

ELF Access Library (libelf, -lelf)

書式

#include < libelf.h>

解説

ELF Access Library (libelf, -lelf) は、アプリケーションが ELF オブジェクトファイルを読み込んで操作でき、 ar(1) アーカイブを読み込むことができる関数群を提供しています。ライブラリによって、バイト順序とワードサイズ独立の方法で、ELF オブジェクトの操作ができ、アプリケーションは、32 と 64 ビットのアーキテクチャとリトルエンディアンとビッグエンディアンのマシンのための ELF オブジェクトを読み込んで、作成することができます。ライブラリは、拡張セクションの番号付けを使用する ELF オブジェクトを処理する能力があります。

このマニュアルページは、ELF ライブラリの機能性の概要を提供するのに役立ちます。ライブラリに含まれている個々の ELF(3) 関数のマニュアルページに、さらなる詳細があります。

ELF 概念

elf(5) で説明されるように、ELF ファイルは、特有の方法でレイアウトされているいくつかのデータ構造を含んでいます。 ELF ファイルは、“実行形式のヘッダ”で始まり、省略可能な“プログラムヘッダテーブル”と省略可能な ELF “セクション”の形式のデータを含んでいます。“セクションヘッダテーブル”は、これらのセクションのデータの内容を説明しています。

ELF オブジェクトには、オブジェクトに使われているアーキテクチャにに自然なマシンワードサイズを示す関連する“ELF クラス”があります。 32 ビットのアーキテクチャのためのオブジェクトには、 ELFCLASS32 の ELF のクラスがあります。 64 ビットのアーキテクチャのためのオブジェクトには、 ELFCLASS64 の ELF のクラスがあります。

また、ELF オブジェクトには、オブジェクトに関連しているマシンアーキテクチャのエンディアンを示す関連する“エンディアン”があります。これは、リトルエンディアンアーキテクチャのための ELFDATA2LSB とビッグエンディアンアーキテクチャのための ELFDATA2MSB です。

また、ELF オブジェクトも API バージョン番号に関連しています。このバージョン番号は、ELF ファイルの個々の構成要素と、これらに関連しているセマンティクスのレイアウトを決定しています。

データ表現と変換

ELF(3) ライブラリは、ELF データ構造の“ネイティブ”表現とそれらの“ファイル”表現を区別しています。

アプリケーションは、“ネイティブ”表現の ELF データで動作します、すなわち、ネイティブのバイト順と、アプリケーションが実行しているプロセッサによって強制された整列を使用します。同じデータの“ファイル”表現は、異なったバイト順序を使用して、これらのネイティブの制約よりオブジェクト整列で異なった制約に従います。

従って、 ELF(3) ライブラリは、それらの表現から、またその表現への変換機能 ( elf32_xlatetof(3), elf32_xlatetom(3), elf64_xlatetof(3)elf64_xlatetom(3)) を提供し、明白な方法で ELF オブジェクトからデータを検索して、格納するより高いレベルの API も提供します。

ライブラリ動作バージョン

概念的に、ELF オブジェクトを操作するために ELF ライブラリを使用するアプリケーションに関連している 3 つのバージョン番号があります:
  • アプリケーションがコンパイルされた ELF バージョン。このバージョンは、アプリケーションによって予想された ABI を決定します。
  • ELF ライブラリを通してアプリケーションによって操作される ELF オブジェクトの ELF バージョン。
  • ELF ライブラリ自体によってサポートされる ELF バージョン (または、バージョンのセット)。

異なるバージョンの ELF オブジェクトで容易に動作するために、 ELF ライブラリは、アプリケーションが必要とする動作するバージョンのライブラリに知らせるために、操作の多くを呼び出す前に elf_version() 関数を呼び出すためのアプリケーションを必要とします。

現在の実装では、すべての 3 つのバージョンは、 EV_CURRENT でなければなりません。

名前空間使用

ELF ライブラリは、次の接頭辞を使用します:
elf_*
クラス独立の関数で使用されます。
elf32_*
32 ビットの ELF オブジェクトで動作する関数で使用されます。
elf64_*
64 ビットの ELF オブジェクトで動作する関数で使用されます。
Elf_*
クラス独立のデータタイプで使用されます。
ELF_C_*
いくつかの関数で使用されるコマンド値で使用されます。これらのシンボルは、 Elf_Cmd 列挙型のメンバとして定義されます。
ELF_E_*
エラー番号で使用されます。
ELF_F_*
フラグで使用されます。
ELF_K_*
これらの定数は、ELF 記述子に関連しているファイルの種類を定義します。 elf_kind(3) を参照してください。シンボルは、 Elf_Kind 列挙型で定義されます。
ELF_T_*
これらの値は、 Elf_Type 列挙型で定義されて、ELF オブジェクトに存在する ELF データ構造のタイプを示します。

記述子

アプリケーションは、記述子を使用してライブラリと交信します。これらは、次の通りです:
Elf
Elf 記述子は、ELF オブジェクト、または ar(1) アーカイブを表します。 elf_begin() または elf_memory() 関数の 1 つを使用してそれを割り付けます。 ELF ファイルにデータを読み込み書き込みするために Elf 記述子を使用することができます。 0 以上の Elf_Scn セクション記述子に Elf 記述子を関連づけることができます。

ELF 記述子を与えて、アプリケーションは、 elf32_getehdr() または elf64_getehdr() 関数を使用して、ELF オブジェクトのクラスに依存する“実行形式ヘッダ”構造を検索することができます。 elf64_newehdr() または elf64_newehdr() 関数を使用して、新しい Ehdr 構造を割り付けることができます。

elf32_getphdr() または elf64_getphdr() 関数を使用して、ELF 記述子に関連している“プログラムヘッダテーブル”を割り付けることができます。新プログラムヘッダテーブルを割り付けるか、または elf32_newphdr() または、 elf64_newphdr() 関数を使用して既存のテーブルをリサイズします。

Elf 構造は、不透明 (サイズおよび形がわからないもの) であり、アプリケーションに見えるメンバはありません。

Elf_Data
Elf_Data データ構造は、メモリで表現されるような ELF ファイルの個々の塊について記述しています。それには、次のアプリケーションに見えるメンバがあります:
uint64_t d_align
ELF セクションを含むデータバッファの in-file の整列。この値は、2 の冪乗なければなりません。
uint64_t d_off
この記述子データが置かれるセクションを含んでいるオフセット。このフィールドは、アプリケーションが ELF オブジェクトのレイアウトの完全な制御を要求しないなら、ライブラリによって計算されます。
uint64_t d_size
この記述子のデータのバイト数。
void *d_buf
メモリのデータへのポインタ。
Elf_Type d_type
この記述子のデータの ELF タイプ (下記参照)。
unsigned int d_version
このバッファ中のデータの操作バージョン。

Elf_Data 記述子は、通常 Elf_Scn 記述子に関連しています。 ELF セクションに関連している既存のデータ記述子は、 elf_getdata() 関数を使用して検索される構造です。 elf_newdata() 関数は、新しいデータ記述子を ELF セクションにアタッチするために使用されます。

Elf_Scn
Elf_Scn 記述子は、ELF オブジェクトのセクションを表します。

それらは、 elf_getscn() 関数を使用して検索されます。アプリケーションは、 elf_nextscn() 関数を使用して既存の ELF オブジェクトのセクションを繰り返します。新しいセクションは、 elf_newscn() 関数を使用して割り付けられます。

Elf_Scn 記述子は、不透明であり、アプリケーションの修正できるフィールドを含んでいません。

サポートしている Elf タイプ

次の ELF データタイプが、ライブラリによってサポートされています。

ELF_T_ADDR
マシンアドレス。
ELF_T_BYTE
バイトデータ。ライブラリは、バイトデータを変換する試みを行いません。
ELF_T_CAP
ソフトウェアとハードウェアのケーパビリティレコード。
ELF_T_DYN
タイプ SHT_DYNAMIC のセクションで使用されるレコード。
ELF_T_EHDR
ELF 実行形式のヘッダ。
ELF_T_HALF
16 ビット符号なしワード。
ELF_T_LWORD
64 ビット符号なしワード。
ELF_T_MOVE
ELF 移動レコード。
ELF_T_NOTE
ELF ノート構造体。
ELF_T_OFF
ファイルオフセット。
ELF_T_PHDR
ELF プログラムヘッダテーブルエントリ。
ELF_T_REL
ELF リロケーデョンエントリ。
ELF_T_RELA
加数がある ELF リロケーデョンエントリ。
ELF_T_SHDR
ELF セクションヘッダエントリ。
ELF_T_SWORD
符号付き 32 ビットワード。
ELF_T_SXWORD
符号付き 64 ビットワード。
ELF_T_SYMINFO
ELF シンボル情報。
ELF_T_SYM
ELF シンボルテーブルエントリ。
ELF_T_VDEF
シンボルバージョン定義レコード。
ELF_T_VNEED
シンボルバージョン要件レコード。
ELF_T_WORD
符号なし 32 ビットワード。
ELF_T_XWORD
符号なし 64 ビットワード。

シンボル ELF_T_NUM は、ライブラリで知られている Elf タイプの数を示します。

次のテーブルは、 elf(5) で定義された ELF セクションタイプとライブラリによってサポートされているタイプの間のマッピングを示します。

セクションタイプ ライブラリタイプ 説明
SHT_DYNAMIC ELF_T_DYN ‘.dynamic’セクションエントリ。
SHT_DYNSYM ELF_T_SYM ダイナミックリンクのシンボル。
SHT_FINI_ARRAY ELF_T_ADDR 終了関数ポインタ。
SHT_GROUP ELF_T_WORD セクショングループのマーカ。
SHT_HASH ELF_T_HASH シンボルハッシュ。
SHT_INIT_ARRAY ELF_T_ADDR 初期関数ポインタ。
SHT_NOBITS ELF_T_BYTE 空セクション。 elf(5) 参照。
SHT_NOTE ELF_T_NOTE ELF ノートレコード。
SHT_PREINIT_ARRAY ELF_T_ADDR 前もって初期化された関数ポインタ。
SHT_PROGBITS ELF_T_BYTE マシンコード。
SHT_REL ELF_T_REL ELF リロケーションレコード。
SHT_RELA ELF_T_RELA 加数があるリロケーションレコード。
SHT_STRTAB ELF_T_BYTE 文字列テーブル。
SHT_SYMTAB ELF_T_SYM シンボルテーブル。
SHT_SYMTAB_SHNDX ELF_T_WORD 拡張セクション番号付けを使用します。
SHT_GNU_verdef ELF_T_VDEF シンボルバージョン定義。
SHT_GNU_verneed ELF_T_VNEED シンボルバージョン要件。
SHT_GNU_versym ELF_T_HALF バージョンシンボル。
SHT_SUNW_move ELF_T_MOVE ELF 移動レコード。
SHT_SUNW_syminfo ELF_T_SYMINFO 追加シンボルフラグ。

機能的なグループ分け

このセクションは、ELF ライブラリの利用可能な機能の簡潔な概要を含んでします。ここにリストされた各関数は、それ自体のマニュアルページにより詳しく説明されています。
アーカイブのアクセス
elf_getarsym()
アーカイブされたシンボルテーブルを検索します。
elf_getarhdr()
オブジェクトのためのアーカイブヘッダを検索します。
elf_getbase()
アーカイブ内のメンバのオフセットを検索します。
elf_next()
ar(1) アーカイブを通して繰り返します。
elf_rand()
ar(1) アーカイブ内をランダムにアクセスします。
データ構造
elf_getdata()
ELF セクションのために変換されたデータを検索します。
elf_getscn()
指定されたセクションのセクション記述子を検索します。
elf_ndxscn()
セクションのインデックスを検索します。
elf_newdata()
新しい Elf_Data 記述子を ELF セクションに追加します。
elf_newscn()
新しいセクション記述子を ELF 記述子に追加します。
elf_nextscn()
ELF オブジェクトのセクションを通して繰り返します。
elf_rawdata()
ELF sectino のための変換されないデータを検索します。
elf_rawfile()
ELF オブジェクトの変換されないファイルの内容へのポインタを返します。
elf32_getehdr(), elf64_getehdr()
ELF オブジェクトの実行形式ヘッダを検索します。
elf32_getphdr(), elf64_getphdr()
ELF オブジェクトのプログラムヘッダテーブルを検索します。
elf32_getshdr(), elf64_getshdr()
Elf_Scn 記述子に関連している ELF セクションヘッダを検索します。
elf32_newehdr(), elf64_newehdr()
ELF オブジェクトの実行形式ヘッダを割り付けます。
elf32_newphdr(), elf64_newphdr()
ELF オブジェクトのプログラムヘッダテーブルを割り付けるか、またはリサイズ (サイズ変更) します。
データ変換
elf32_xlatetof(), elf64_xlatetof()
ELF データ構造をネイティブ表現からファイル表現に変換します。
elf32_xlatetom(), elf64_xlatetom()
ELF データ構造をファイル表現からネイティブ表現に変換します。
エラー報告
elf_errno()
現在のエラーを検索します。
elf_errmsg()
現在のエラーの人間に読み込み可能な記述を検索します。
初期設定
elf_begin()
ar(1) アーカイブまたは ELF オブジェクトを与えられたファイル記述子でオープンします。
elf_end()
ELF 記述子をクローズして、すべてのリソースを解放します。
elf_memory()
メモリ領域に存在する ar(1) アーカイブまたは ELF オブジェクトをオープンします。
elf_version()
操作バージョンを設定します。
IO 制御
elf_cntl()
ELF 記述子とその基本的なファイルの間の関連性を管理します。
elf_flagdata()
Elf_Data 記述子がダーティ (汚い) とマークします。
elf_flagehdr()
ELF 記述子の ELF 実行形式ヘッダがダーティ (汚い) とマークします。
elf_flagphdr()
ELF 記述子の ELF プログラムヘッダテーブルがダーティ (汚い) とマークします。
elf_flagscn()
Elf_Scn 記述子がダーティ (汚い) とマークします。
elf_flagshdr()
ELF セクションヘッダがダーティ (汚い) とマークします。
elf_setshstrndx()
ELF オブジェクトのセクション名文字列テーブルのインデックスを設定します。
elf_update()
ELF オブジェクトのレイアウトを再計算し、オプションで、変更されたオブジェクトを基本的なファイルに書き戻します。
問い合わせ
elf32_checksum(), elf64_checkum()
ELF オブジェクトのチェックサムを計算します。
elf_getident()
ELF オブジェクトの識別バイトを検索します。
elf_getshnum()
ELF オブジェクトのセクションの数を検索します。
elf_getshstrndx()
ELF オブジェクトのセクション名文字列テーブルのセクションインデックスを検索します。
elf_hash()
文字列の ELF ハッシュ値を計算します。
elf_kind()
ELF 記述子に関連しているオブジェクトの種類を問い合わせます。
elf32_fsize(), elf64_fsize()
ELF タイプのファイル表現のサイズを返します。

ELF オブジェクトレイアウトの制御

操作の通常モードで、ライブラリは、セクションのオフセットを計算し、アプリケーションによってさらなる調整の必要性なしで ELF 記述子のセクションの内容に基づいて整列します。

しかしながら、アプリケーションが ELF ファイルのレイアウトの完全な管理を引き受けるなら、 elf_flagelf(3) を使用して ELF 記述子に ELF_F_LAYOUT フラグを設定し、続いて、ライブラリが、ファイルをレイアウトするとき、アプリケーションによって指定されたデータオフセットと整列を使用します。ファイルレイアウトのアプリケーション制御は、 elf_update(3) マニュアルページに、より詳しく説明されています。

セクション間のギャップは、関数 elf_fill() によって設定された fill (充填) 文字で満たされます。

エラー処理

エラーに遭遇する場合に、これらのライブラリ関数は、内部のエラー番号を設定して、特別なリターン値を返すことによって、エラーの存在を示します。アプリケーションは、 elf_errno(3) を呼び出すことによって、現在のエラー番号をチェックすることができます。記録されたエラーの人間に読み込み可能な記述は、 elf_errmsg(3) を呼び出すことによって、利用可能です。

メモリ管理規則

ライブラリは、ELF 記述子に関連しているすべての Elf_ScnElf_Data 記述子の経過を追い、記述子が elf_end(3) を使用してクローズされるとき、それらを復元します。したがって、アプリケーションは、ELF ライブラリによって割り付けられたデータ構造で free(3) を呼び出してはなりません。

反対に、ライブラリは、割り付けられていないデータを解放しません。例として、アプリケーションは、新しい Elf_Data 記述子を割り付けるために elf_newdata(3) を呼び出し、 malloc(3) を使用して割り付けられたメモリの領域を指すように記述子の d_off メンバを設定することができます。この領域を解放することは、アプリケーション責任ですが、ライブラリは、 Elf_Data 記述子自体によって使用される空間を取り戻します。

関連項目

gelf(3), elf(5)

歴史

オリジナルの ELF(3) API は、Unix System V のために開発されました。 ELF(3) API の現在の実装は、 FreeBSD 7.0 で登場しました。

作者

ELF ライブラリは、 Joseph Koshy <jkoshy@FreeBSD.org>によって書かれました。
October 21, 2007 FreeBSD