総合手引 | セクション 5 | English | オプション |
#include <a.out.h>
バイナリファイルは最大で 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 となります。
A.OUT (5) | June 5, 1993 |
総合手引 | セクション 5 | English | オプション |
このマニュアルページサービスについてのご意見は Ben Bullock にお知らせください。 Privacy policy.
“ | A typical Unix /bin or /usr/bin directory contains a hundred different kinds of programs, written by dozens of egotistical programmers, each with its own syntax, operating paradigm, rules of use ... strategies for specifying options, and different sets of constraints. | ” |
— The Unix Haters' handbook |