スポンサーリンク

A.OUT(5) FreeBSD ファイルフォーマットマニュアル A.OUT(5)

名称

a.out − 実行可能バイナリファイルのフォーマット

書式

#include <a.out.h>

解説

インクルードファイル <a.out.h> では 3 つの構造体といくつかのマクロが宣言 されています。これらの構造体は、このシステムで実行可能な機械語コードファ イル (‘バイナリ’) のフォーマットを規定します。

バイナリファイルは最大で 7 つのセクションから構成されます。これらのセク ションを順にあげると以下のようになります:

       exec ヘッダ

バイナリファイルをメモリ上にロードして実行するた めにカーネルが用いるパラメータを含んでいます。こ れらのパラメータはリンクエディタ ld(1) がバイナリ ファイルを他のバイナリファイルと結合する際にも用 いられます。このセクションは唯一の必須セクション です。

テキストセグメント
プログラムが実行される際にメモリ上にロードされる 機械語コード及び関連データを含んでいます。読み込 み専用でロードされる場合があります。

データセグメント
初期化済データを含んでいます。常に書き込み可能な メモリ上にロードされます。

テキストリロケーション
バイナリファイル結合時にテキストセグメント内のポ インタを修正するために、リンクエディタによって用 いられるレコードを含んでいます。

データリロケーション
前出のテキストリロケーションセクションと似ていま すが、データセグメント内のポインタ修正用です。

シンボルテーブル
バイナリファイル間で名前付きの変数や関数 (‘シンボ ル’) のアドレス相互参照を解決するために、リンクエ ディタによって用いられるレコードを含んでいます。

string table
シンボル名に対応する文字列を含んでいます。

全てのバイナリファイルは次の exec 構造体で始まります:

struct exec {

unsigned long

a_midmag;

unsigned long

a_text;

unsigned long

a_data;

unsigned long

a_bss;

unsigned long

a_syms;

unsigned long

a_entry;

unsigned long

a_trsize;

unsigned long

a_drsize;

};

これらのフィールドは以下の機能を持っています:

       a_midmag

このフィールドはホストのバイト順 (host byte-order) で格納されま す。このフィールドはいくつかのサブコンポーネントを持っており、 それらは以下のマクロ N_GETFLAG(), N_GETMID(), N_GETMAGIC() で参 照され、マクロ N_SETMAGIC() で設定されます。

マクロ N_GETFLAG() は以下のフラグを返します:

EX_DYNAMIC
この実行可能ファイルがランタイムリンクエディタの サービスを要求することを示します。

EX_PIC
このオブジェクトファイルが位置独立 (position independent) なコードを含んでいることを示します。こ のフラグは ‘-k’ フラグ指定時に as(1) によって設定さ れ、必要なら ld(1) はこれを保存します。

EX_DYNAMIC と EX_PIC の両方がセットされている場合、そのオブジェ クトファイルは位置独立な実行可能イメージです (例: 共有ライブラ リ)。これはランタイムリンクエディタによってプロセスのアドレス空 間にロードされます。

マクロ N_GETMID() はマシン識別コード (machine-id) を返します。 これは、バイナリファイルが実行されるべきマシンを示しています。

N_GETMAGIC() はマジックナンバを示します。マジックナンバはバイナ リファイル種別を一意に識別し、様々なロード方法を区別します。こ のフィールドは以下の値のいずれか 1 つを含んでいなければなりませ ん:

OMAGIC
テキストセグメントとデータセグメントはヘッダの直後にあ り、連続しています。カーネルはテキスト/データセグメント の両方を書き込み可能メモリ領域にロードします。

NMAGIC
OMAGIC と同様、テキスト/データセグメントはヘッダの直後 にあり、連続しています。しかし、カーネルはテキストセグ メントを読み込み専用メモリ領域にロードし、テキストに続 くページ境界から始まる書き込み可能メモリ領域にデータセ グメントをロードします。

ZMAGIC
カーネルは各々のページを必要に応じてバイナリからロード します。ヘッダ、テキストセグメント及びデータセグメント はいずれも、ページサイズの倍数の大きさになるよう、リン クエディタによってパディングされます。カーネルがテキス トセグメントからロードしたページは読み込み専用ですが、 データセグメントからロードしたページは書き込み可能で す。

a_text
テキストセグメントのサイズ (バイト単位) を保持します。

a_data
データセグメントのサイズ (バイト単位) を保持します。

a_bss
‘bss セグメント’ のバイト数を保持します。この値はカーネルが最初 の break 値 (brk(2)) をデータセグメントの後ろに設定するのに用い られます。カーネルは、ここに示されるサイズの書き込み可能メモリ 領域がデータセグメントの後ろに用意され、それらの初期状態が 0 に なるように、プログラムをロードします。 (bss = block started by symbol:シンボルで開始するブロック)

a_syms
シンボルテーブルセクションのサイズ (バイト単位) を保持します。

a_entry
カーネルがバイナリファイルをロードした後の、プログラムのエント リポイントのメモリアドレスを保持します。カーネルは、このアドレ スにある機械命令からプログラムの実行を開始します。

a_trsize
テキストリロケーションテーブルのサイズ (バイト単位) を保持しま す。

a_drsize
データリロケーションテーブルのサイズ (バイト単位) を保持しま す。

インクルードファイル <a.out.h> では、 exec 構造体を用いて一貫性をテストし たりバイナリファイル中のセクションオフセットを知るためのマクロが定義され ています。

N_BADMAG(exec)
a_magic
フィールドに、認識できない値が含まれている場合、 非 0 を返します。

N_TXTOFF(exec)
バイナリファイルにおけるテキストセグメントの先頭のバイト オフセットを返します。

N_SYMOFF(exec)
シンボルテーブルの先頭のバイトオフセットを返します。

N_STROFF(exec)
文字列テーブルの先頭のバイトオフセットを返します。

リロケーションレコードは、 relocation_info 構造体で規定される標準フォー マットです:

struct relocation_info {

int

r_address;

unsigned int

r_symbolnum : 24,

r_pcrel : 1,

r_length : 2,

r_extern : 1,

r_baserel : 1,

r_jmptable : 1,

r_relative : 1,

r_copy : 1;

};

relocation_info 構造体の各フィールドは以下のように用いられます:

       r_address

リンクエディットが必要なポインタのバイトオフセットを保持しま す。テキストリロケーションオフセットはテキストセグメントの先 頭から、データリロケーションオフセットはデータセグメントの先 頭から、それぞれ計算します。リンクエディタはこのオフセットに ストアされている値を加算し、このリロケーションレコードを用い て計算した新しい値に変換します。

r_symbolnum
シンボルテーブルにおけるシンボル構造体の順序番号 ( バイトオ フセット ではありません ) を保持します。リンクエディタはこの シンボルの絶対アドレスを解決した後、そのアドレスをリロケー ション中のポインタに加算します。 (もし r_extern ビットが立っ ていなければ状況は異なります。以下を参照して下さい。)

r_pcrel
もしこのビットが立っていれば、リンクエディタは、PC 相対アド レッシングを用いる機械語命令の一部であるポインタを更新してい るものと仮定します。リロケートされるポインタのアドレスは、実 行中のプログラムがそれを用いる際に、暗黙的にその値に加算され ます。

r_length
ポインタの長さを 2 を底とする対数で表したバイト単位で保持し ます。 1 バイトディスプレースメントなら 0、 2 バイトディスプ レースメントなら 1、 4 バイトディスプレースメントなら 2 とな ります。

r_extern
このリロケーションが外部参照を必要としている場合にセットされ ます。リンクエディタは、シンボルアドレスを用いてこのポインタ を更新しなければなりません。 r_extern ビットが立っていない場 合、そのリロケーションは ‘ローカル’ です。リンクエディタは、 シンボル値の変化ではなく、各セグメントのロードアドレスの変化 に応じてポインタを更新します (ただし、 r_baserel もセットさ れている場合(後述)は除きます)。この場合、 r_symbolnum フィー ルドの内容は n_type の値となります(後述)。リンクエディタは、 この型フィールドから、リロケートされるポインタがどのセグメン トを指しているのかの情報を得ます。

r_baserel
セットされている場合、 r_symbolnum フィールドで指定される場 合のように、このシンボルはグローバルオフセットテーブルへのオ フセットにリロケートされます。実行時に、グローバルオフセット テーブル中の、このオフセット位置にあるエントリが、シンボルの アドレスを持つようにセットされます。

r_jmptable
セットされている場合、 r_symbolnum フィールドで指定される場 合のように、このシンボルはプロシージャリンケージテーブルへの オフセットにリロケートされます。

r_relative
セットされている場合、このリロケーションは、このオブジェクト ファイルが含まれるイメージの (実行時の) ロードアドレスとの相 対値となります。この種のリロケーションは共有オブジェクトにの み現れます。

r_copy
セットされている場合、このリロケーションレコードは、その内容 を r_address で指定される位置にコピーしなければならないシン ボルを示します。コピー処理は、実行時のリンクエディタによっ て、共有オブジェクト中の適切なデータアイテムから行われます。

シンボルは名前とアドレスを対応づけます (より一般的には、文字列を値へ対応 づけます)。リンクエディタがアドレスを調節するため、絶対値が割り当てられる まではシンボルを用いてアドレスを表現しなければなりません。シンボルは、シ ンボルテーブル中の固定長のレコードと、文字列テーブル中の可変長の名前から 成ります。シンボルテーブルは nlist 構造体の配列です:

struct nlist {

union {

char

*n_name;

long

n_strx;

} n_un;

unsigned char

n_type;

char

n_other;

short

n_desc;

unsigned long

n_value;

};

これらのフィールドは以下のように用いられます:

       n_un.n_strx

このシンボルの名前の、文字列テーブルでのバイトオフセットを保 持します。プログラムが nlist(3) 関数を用いてシンボルテーブル をアクセスする場合、このフィールドは、メモリ中の文字列へのポ インタである n_un.n_name フィールドに置き換えられます。

n_type
リンクエディタがシンボル値の更新方法を決定するのに用いられま す。 n_type フィールドは、ビットマスクを用いた 3 つのサブ フィールドに分けられます。リンクエディタは N_EXT ビットが セットされているシンボルを ‘external’ シンボルとして扱い、他 のバイナリファイルからの参照を許可します。 N_TYPE マスクはリ ンクエディタに必要なビットを選択します:

N_UNDF
未定義シンボル。リンクエディタは、他のバイナリファイ ル中の同じ名前の外部シンボルを探してこのシンボルの絶 対値を決定しなければなりません。特別な場合として、も し n_value フィールドが非 0 で、リンクエディット対象 のどのバイナリファイルもこのシンボルを定義していない 場合、リンクエディタはこのシンボルが bss セグメント 中のアドレスであるとみなし、 n_value に等しいバイト 数の領域を予約します。もしこのシンボルが複数のバイナ リファイル中で未定義となっており、それらのバイナリ ファイル間でサイズが異なっている場合、リンクエディタ はそれらのサイズの最大値を選びます。

N_ABS
絶対シンボル。リンクエディタは絶対シンボルは更新しま せん。

N_TEXT
テキストシンボル。このシンボルの値はテキストアドレス であり、リンクエディタはバイナリファイルをマージする 際、その値を更新します。

N_DATA
データシンボル。 N_TEXT と同様ですが、データアドレス を表します。テキストシンボル及びデータシンボルの値 は、ファイルオフセットではなくアドレスです。ファイル オフセットを復元するために、対応するセクションの先頭 のロードアドレスを見つけてそれを減じ、次にそのセク ションのオフセットを加算する必要があります。

N_BSS
bss シンボル。テキストシンボルやデータシンボルと似て いますが、バイナリファイル中に対応するオフセットを持 ちません。

N_FN
ファイル名シンボル。バイナリファイルをマージする際、 リンクエディタはバイナリファイルの他のシンボルの前に このシンボルを挿入します。このシンボルの名前はリンク エディタに与えられたファイル名で、シンボルの値はバイ ナリファイルから得た先頭テキストアドレスです。ファイ ル名シンボルはリンクエディト処理やロード処理には不要 ですが、デバッガには有用な情報です。

N_STAB マスクは gdb(1) 等のシンボリックデバッガに必要なビッ トを選択します。その値は stab(5) に示されています。

n_other
このフィールドは、 n_type フィールドで決定されるセグメントに 関して、そのシンボルのロケーションとは独立したシンボルの特質 に関する情報を提供します。現在のところ、 n_other フィールド の下位 4 ビットは AUX_FUNC あるいは AUX_OBJECT のいずれかを とります (これらの定義については <link.h> を参照してくださ い)。 AUX_FUNC はシンボルと呼び出し可能な関数を関連づけ、他 方、 AUX_OBJECT はシンボルとデータを関連づけます。これらの関 連はテキストセグメント/データセグメントの別とは無関係です。 このフィールドは、 ld(1) が動的な実行可能形式を構築するため に使うことを意図しています。

n_desc
デバッガ用に予約されており、リンクエディタはこのフィールドを 全く変更しません。デバッガによって異なった目的に使われます。

n_value
シンボルの値を保持します。テキスト, データおよび bss シンボ ルの場合、その値はアドレスです。他のシンボル (例えばデバッガ シンボル等) の場合、その値は様々です。

文字列テーブルは unsigned long 型の長さと、それに続くナル終端のシンボル文 字列から成ります。この長さは、テーブル全体のサイズをバイト単位で表しま す。つまり、その最小値 (言い替えれば、最初の文字列のオフセット) は、 32 ビットマシンでは常に 4 となります。

関連項目

as(1), gdb(1), ld(1), brk(2), execve(2), nlist(3), core(5), elf(5), link(5), stab(5)

歴史

インクルードファイル <a.out.h> は Version 7 AT&T UNIX で登場しました。

バグ

必ずしも全てのサポート対象アーキテクチャが a_midmag フィールドを用いるわ けではないので、あるバイナリがどのようなアーキテクチャ上で実行されるのか は、実際のマシンコードを調べない限り判定困難な可能性があります。マシン ID があったとしても、 exec ヘッダのバイト順はマシン依存です。

FreeBSD 10.0 June 5, 1993 FreeBSD 10.0

スポンサーリンク