「オブジェクトファイル」の版間の差分

削除された内容 追加された内容
→‎シンボルテーブル: →‎リロケーション: はそれぞれのトピックに説明の内容と重複するため外出しとした。→‎セグメント: en:Object_file 12:39, 30 December 2019 UTC より抜粋して翻訳。
1行目:
{{出典の明記|date=2019-11-21}}
'''オブジェクトファイル''' ({{en|object file}}) または'''オブジェクトコード''' ({{en|object code}}) とは、[[コンパイラ]]が[[ソースコード]]を処理した結果生成される(たいていはアセンブリ言語による assembler code file と、アセンブラによるそれのアセンブルを経由している)、コード生成の結果にして[[バイナリ]]コードを含む中間的なデータ表現のファイルである。'''オブジェクトファイル'''は[[共有ライブラリ]]のようにも使わることがある。

中身は、[[機械語]][[バイナリ]]とそれに付随、異なるモジュール間の相互参照を解決する[[シンボルテーブル]][[リロケータブルバイナリ|リロケーション]]テーブルといった付加、スタック巻き戻し情報であり、[[コメント]]、さらにデバッグ支援情報や近年はリンク時最適化などのめの高度な情報はデバッグに使用される[[メタデータ]]が含まれる場合もある。
 
オブジェクトファイル群を[[リンケージエディタ|リンク]]することにより、最終的な[[実行ファイル]]や[[ライブラリ]]が作成される。オブジェクトファイルのほとんどは[[機械語]](コンピュータの[[CPU]]が直接実行できるコード)であり、'''オブジェクトファイルフォーマット'''は[[コンパイラ]]や[[アセンブリ言語|アセンブラ]]が生成するオブジェクトファイルの[[ファイルフォーマット]]である。
7 ⟶ 9行目:
オブジェクトファイルにはオブジェクトコードだけでなく、[[リンケージエディタ|リンカ]]が[[実行ファイル]]や[[ライブラリ]]を作成するときに使用する[[リロケータブルバイナリ|リロケーション]]情報、プログラム内のシンボル情報、[[デバッグ]]情報などが含まれる。
 
オブジェクトファイルフォーマットには様々なものがある。本来各コンピュータはそれぞれオリジナルのフォーマットを持っていたが、[[UNIX]]や他の移植性のあるオペレーティングシステムが普及するに従って[[COFF]]や[[Executable and Linkable Format|ELF]]などのフォーマットが定義され、様々なシステムで使われるようになった。リンカの入力と出力に同じファイルフォーマットを使うのが一般的であるため、オブジェクトファイルフォーマットは実行ファイルフォーマットでもある<ref>{{cite book|last=IBM Corporation|title=IBM OS Linkage Editor and Loader|year=1973|url=http://www.bitsavers.org/pdf/ibm/360/os/R21.7_Apr73/GC28-6538-10_Linkage_Editor_Rel_21_Apr73.pdf}}</ref>{{rp|p.16}}
 
オブジェクトファイルフォーマットの設計や選択はシステム全体の設計に関わる問題である。リンカの性能に直接関係してくるため、プログラム開発の効率に影響する。また、同じフォーマットを実行ファイルでも使用する場合、プログラムの起動時間にも影響する。多くのオブジェクトファイルフォーマットでは同種のデータを集めた形式でブロック化されており、[[仮想記憶]]システムで必要に応じてページ単位にロードすることができ、そのまま実行可能である。
13 ⟶ 15行目:
最も単純なオブジェクトファイルフォーマットとして[[MS-DOS]]の[[COMファイル|COM]]フォーマットがある。COMファイルは固定アドレスにロードされるバイト列から構成されている。他のフォーマットは内部構造があり、何ページにも渡る仕様書でその構造が規定されている。
 
=== セグメント ===
デバッグ情報はCOFFなどのフォーマットでは必須の部分だが、[[stabs]]、[[DWARF]]などのフォーマットでは半ば独立したフォーマットとなっている。
殆どの種類のオブジェクトファイル形式は、一般的な[[メモリ管理]]の手法のひとつである "[[セグメント方式|メモリセグメント]]" という用語に由来する "セグメント" と呼ばれる単位でデータを分割して保持しており、それぞれデータの種類が異なる。プログラムが[[ローダ]]によってメモリに読み込まれると、ローダはメモリの複数の領域をプログラムに割り当てる。
 
典型的なオブジェクトファイルフォーマットでサポートされるデータ種別は以下の通りである。
[[GNUプロジェクト]]の[[BFDライブラリ]]は様々なフォーマットのオブジェクトファイルについての共通の[[アプリケーションプログラミングインタフェース|API]]を提供する。
* [[ヘッダ_(コンピュータ)|ヘッダー]]情報 (ディスクリプティブ/コントロール情報)
* コードセグメント ("テキストセグメント"、実行形式コード)
* データセグメント (初期値を持つ静的変数)
* 読み取り専用データセグメント (''RODATA''、初期値を持たない静的定数)
* BSS セグメント (初期値を持たない変数や定数といった静的データ)
* リンキングのための外部定義と参照情報
* [[リロケータブルバイナリ|リロケーション]]情報
* [[動的リンク|ダイナミックリンク]]情報
* [[デバッグ]]情報
 
典型的オブジェクトファイルフォーマッ内のセグメンでサポートされるデータ種別として、テキストセグメントの定義で決められた規則に従いリンカが結合する。例えばデータ[[DOS]]では特別なセグメント、BSS の名前を決めたり結合されるべきかを定義した規則存在す<ref name="pc asm" >{{citation
|last=Irvine |first=Kip R. |year=1993
|title=Assembly language for the IBM-PC |edition=2nd
|publisher=Macmillan |place=New York |isbn=0-02-359651-1
}}</ref>。
 
== リロケーション ==
リロケーション(再配置)とは、オブジェクトファイル内のシンボリックな参照を具体的な[[メモリアドレス]]に置き換えることを意味する。一般にオブジェクトファイルはその中のコードが0番地から始まるものとしてコードが生成されている。従って、実際に実行する前にそのコードが置かれたアドレスに応じてコードの調整をしなければならない。
 
デバッグ情報はCOFFなどのフォーマットでは必須の部分だが、[[stabs]]、[[DWARF]]などのフォーマットでは半ば独立したフォーマットとなっている。
リロケーションは以下の2段階で行われる。
 
[[GNUプロジェクト]]の[[BFDライブラリ]]は様々なフォーマットのオブジェクトファイルについての共通の[[アプリケーションプログラミングインタフェース|API]]を提供する。
# 各オブジェクトファイルにはテキスト、データ、[[.bss|BSS]] といったセクションが存在する。全オブジェクトファイルをひとつの実行ファイルにまとめる際にそれらセクションを種類ごとにまとめるように配置する。そして、各セクションの配置アドレスを決定する。これによって各シンボルのアドレスが決定される。この時点で各シンボル(関数名や変数名)はユニークな実行時アドレスが割り当てられる。
# 各セクションでシンボルを参照している箇所を修正して正しい実行時アドレスを参照するようにする。
 
オブジェクトファイル内のリロケーション情報とは、各セクションをメモリに配置する際の先頭アドレスとセクションサイズを意味する。テキストやデータなどのセクションはファイル内に実体があり、ファイルの先頭からのオフセット(をページサイズで割った余り)とメモリ上に配置する際のアドレスのページ内オフセットが一致するように配置される。BSSは初期値を持たない[[広域変数]]域であり、ファイル内に実体がない。<!-- 言葉で説明すると難しい -->
 
[[ライブラリ#動的リンク|ダイナミックリンクライブラリ]]を使用する実行ファイルでは未解決シンボルに関するシンボルテーブル状のデータをリロケーション情報として持っていて、実行時にローダーがリロケーションを行う。
 
== シンボルテーブル ==
[[シンボルテーブル]]はコンパイラなどが使用するデータ構造であり、ソースコード内の各種シンボル(関数名、変数名)の位置、タイプ、スコープなどを格納するものである。[[ハッシュテーブル]]形式になっていることが多く、コンパイル中ずっと保持される。コンパイル後の実行ファイルにシンボルテーブルを含めることもでき、シンボリックな[[デバッグ]]に使用したり、統計情報や診断情報を実行時に得るのに使ったりする。[[ライブラリ#動的リンク|ダイナミックリンクライブラリ]]では、シンボルテーブルをリロケーション情報として使用する。
 
== フォーマット ==