| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
GNU リンカは, オブジェクトファイルとアーカイブファイルをアクセスするのに
BFD ライブラリを使っている. このライブラリは, オブジェクトファイルを
扱う時に, そのオブジェクトファイル形式が何であっても, 同じルーチンを
使うのを可能にする. 異なるオブジェクトファイル形式は, 単に新しい
BFD バックエンドをつくって, それをライブラリに追加するだけで
対応できる. ただし, 実行時のメモリを節約するために, リンカや関係ツールは,
普通は利用可能なオブジェクトファイル形式の一部だけに対応するように
コンフィギュレーションされる. objdump -i
(see section `objdump' in The GNU Binary Utilities)
を使うと, 読者のところのコンフィギュレーションで利用可能な
形式を全て表示する.
大概の実装がそうであるように, BFD はたくさんの矛盾する要件の折衷案 と言える. BFD の設計に一番影響を及ぼす要因は, 効率である. 形式間の変換に使われる時間は全て, BFD が入っていなかった頃には 費やされることのなかった時間である. これは, 抽象化による恩恵で 部分的には相殺される. BFD によりアプリケーションとバックエンドが 簡単になるので, 速度を追求するためにアルゴリズムを改善するのに, 時間と注意をさらに振り向けられるようになったのである.
BFD による方法の小さなゆがみで読者が気をつけなければならないのは, 情報損失の可能性である. BFD の仕組みを使う時には有用な情報が失われる 可能性がある場所が二箇所ある. 変換時と出力時である. See section 5.1.1 情報の損失.
5.1 動作の仕組み: BFD の概要
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
オブジェクトファイルの別の情報が必要になると、BFD はそのファイルの 別の区画から読み込みを行ない、処理を行なう。例えば、リンカが 非常に良く使う操作にシンボルテーブルの処理がある。各バックエンドは、 シンボルのオブジェクトファイル注での表現と内部の正規形との変換を 行なうルーチンを提供している。リンカがあるオブジェクトファイルの シンボル表を要求すると、BFD は、適切な BFD バックエンドのルーチンを ポインタを経由して呼び出し、シンボル表を読み込んで正規形に変換を行なう。 そうするとリンカはその正規形に対し操作を行なう。リンクが完了し、 リンカが出力ファイルのシンボル表を書き出すと、別の BFD バックエンド ルーチンが呼ばれて、新しく作成されたシンボル表を受けとって、 選ばれた出力形式に変換する。
5.1.1 情報の損失 5.1.2 BFD 正規オブジェクトファイル形式
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
出力の際には情報が失われる可能性がある。 BFD がサポートしている
出力形式は同一の機能を提供しているわけではない。ある形式で
記述可能な情報が他の形式では入れる場所がないということがある。
一つの例は b.out のアラインメント情報である。a.out形式の
ファイルには含まれるデータについてのアラインメントを入れておく場所が
ないので、b.out のファイルをリンクして a.out の
イメージを作ると、アラインメント情報は出力ファイルに伝わらないのである。
(リンカは内部的にアライメント情報を使っているので、リンク自体は
正しく行なわれる。)
もう一つの例は COFF のセクション名である。COFF ファイルに入れられる セクション数には制限がなく、それぞれテキスト文字列のセクション名がある。 リンクのターゲットの形式がたくさんセクションを保持できなかったり、 名前がないもの(例えば Oasys 形式)だと、リンクは単純には行なえない。 この問題は、入力セクションから出力セクションへの望ましい対応を リンカコマンド言語で記述することで克服できる。
正規化の過程で情報が失われる可能性がある。 外部形式に対する、BFD の内部正規形は完全には網羅していない。 入力形式には、内部的に直接的に表現できない構造が存在する。 これは、BFD のバックエンドは、外部形式から内部形式への変換と 外部形式に戻す際に全ての可能なデータを充分には保持できないという ことを意味する。
この制限が問題になるのは、アプリケーションがある一つの形式で
読み込んで、それとは別の形式で書き出す場合だけである。
各 BFD バックエンドには可能な限りたくさんのデータを保持する
責任があり、内部 BFD 正規形には BFD の中心部からは隠されている、
そのバックエンドにしか公開されていない構造体がある。
あるファイルが一つの形式で読み込まれると BFD とアプリケーション用に
正規形が作られる。同時に、バックエンドがたくわえない限り失われて
しまう情報を、バックエンドが格納する。次にデータが同じ形式で
書き戻されると、バックエンドルーチンは、事前に準備された情報だけでなく、
BFD の中核部が提供する正規形も使えるようになる。バックエンド間で
共通する部分が多いので、ビッグエンディアンの COFF をリトルエンディアンの
COFF に、あるいは a.out を b.out にリンクしたり、コピーする
時には情報の損失はない。形式を混ぜてリンクすると、目的のファイル形式
と異なる形式のファイルの情報だけが失われる。
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
最も情報が失われる可能性が大きいのは、ソース形式が提供する情報と、 正規形で蓄える情報と、目的形式が必要とする情報の間に重なる部分が 最も少ない時である。正規形の概要を説明しておけば、変換の際に どんな種類のデータが保存されると期待して良いかを理解する助けに なるだろう。
ZMAGIC のファイルなら、デマンドページング可ビットと
書き込み防止ビットの両方が立てられる。ターゲットのバイト順は
ファイル単位で格納されるので、ビッグエンディアンのファイルと
リトルエンディアンのファイルはお互い一緒に使うことができる。
ld は、
全くことなる形式のシンボルの集まりを問題なく扱うことができる。
普通のグローバルシンボルと単純なローカルシンボルは出力の際にも
保持されるので、出力ファイル(その形式はなんであれ)には、
関数と、グローバル変数、静的変数、コモン変数を指すシンボルが
保持される。シンボル情報の中には残す意味のないものがある。a.out
では、型情報はシンボル表に長いシンボル名として格納される。この情報は、
ほとんどの COFF デバッガには意味がない。GNU リンカには、こういう
シンボル情報を捨てるコマンド行オプションがある。
シンボルには、1 ワードで表される型情報が含まれているので、 オブジェクトファイル形式がシンボル内にシンボルの型情報を入れられる ものであり(例えば、COFF、IEEE、Oasys)、その型が 1 ワードに収まる程度の 簡単なものであれば(集合体以外のすべてと考えて良い)、その型情報は保存される。
| [ << ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |