web-dev-qa-db-ja.com

オブジェクトファイルには何が含まれていますか?

CまたはC++でのコンパイルのさまざまな段階で、オブジェクトファイル(つまり、any_name.oファイル)が生成されることを知っています。この.oファイルには何が含まれていますか?バイナリファイルなので開くことができません。

誰か助けてくれませんか?オブジェクトファイルの内容は、主にUnixで使用するコンパイラに依存していますか?

45
Vijay

オブジェクトファイルには多くのものを含めることができます。基本的には、以下のリストの一部またはすべてです。

  • シンボル名
  • コンパイル済みコード
  • 定数データ、例えば。ひも
  • インポート-コンパイルされたコードが参照するシンボル(リンカーによって修正されます)
  • エクスポート-オブジェクトファイルが他のオブジェクトファイルで使用できるようにするシンボル。

リンカは、すべてのインポートとエクスポートを照合し、コンパイルされたコードを修正して正しい関数が呼び出されるようにすることで、オブジェクトファイルの束を実行可能ファイルに変換します。

47
Roddy

いくつかの標準化された形式(COFF、UnixのELF)があります。基本的に、それらは実行可能ファイルに使用されるものと同じ形式のバリアントですが、一部の情報が欠落しています。これらの欠落情報は、リンク時に完成します。

オブジェクトファイル形式には、基本的に同じ情報が含まれています。

  • コンパイルの結果のバイナリコード(ターゲットプロセッサ用)
  • プログラムのその部分で使用される静的データ(定数文字列など)。 BSS(エクスポートされたデータ)とテキスト(プログラムによって変更されないデータ)をさらに細かく区別できます。しかし、それはコンパイラーとリンカーにとって最も重要です。バイナリコードと同様に、データもターゲット(ビッグエンディアン、リトルエンディアン、32ビット、64ビット)に依存することに注意してください。
  • プログラムのこの部分によってエクスポートされたシンボルのテーブル(主に機能するエントリポイント)
  • プログラムのこの部分で使用される外部シンボルのテーブル

オブジェクトが一緒にリンクされると、外部シンボルを参照するコードの部分は実際の値に置き換えられます(それでもまだ単純化されすぎているため、プログラムの実行時にロード時に行われる最後の部分がありますが、それは考え)。

オブジェクトファイルには、インポートとエクスポートの解決に厳密に必要なシンボル情報がさらに含まれている場合があります(デバッグに役立ちます)。その情報はstripコマンドを使用して削除できます。

8
kriss

最初に wikiページ を読んでください。 objdumpを使用して、このようなファイルを調べることができます:)

5

このようなことにはfileコマンドを使用します。これは、最新のLinuxシステムの [〜#〜] elf [〜#〜] オブジェクトファイルです。例えば。 32ビットx86用にコンパイルされた場合。

ELF 32-bit LSB relocatable, Intel 80386, version 1 (SYSV), not stripped

対照的に、動的にリンクされた実行可能ファイルは次のようになります。

ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.15, not stripped

セクション名を含むヘッダーを表示するには、次を使用できます。

objdump -x any_name.o

分解するには:

objdump -d any_name.o
4

まず、バイナリファイルを開くことができます!怖がらないでください、ちょうどいいツールが必要です!バイナリデータであるため、テキストエディターはもちろん正しいツールではありません。適切なツールは、16進エディタ、emacsのような高度なエディタ、または単に「16進」表現でバイトを「出力」する代わりに、データの解釈をあなたに任せ、その特定の形式と「あるレベルでデータを適切に解釈します(たとえば、GIMPはPNGファイルを画像として解釈して表示し、PNGアナライザーはPNGセクション内のデータを「分解」して、特定のバイトでフラグを示します...など)。

あなたの場合、一般的な答えは、オブジェクトファイルにはコンパイルされたコード(およびデータ)に加えて、リンカが必要とするすべての追加情報が含まれ、最終的にはそれ以上になるということです。

これらの情報がどのように「編成される」か、場合によっては「最終的にはより多く」が何で構成されるかは、特定のオブジェクト形式によって異なります。いくつかの可能性をリストしたウィキペディアのリンクには、 thisthisthisthis ...

これらのそれぞれには、コンテンツを分析するためのツールがあります。例えばELFの場合はreadelf、いくつかの形式の場合はobjdumpobjdump -iを試してください)コンパイル方法によって異なります。

3
ShinTakezou

オブジェクトファイルはコンパイルされたソースです。

これは、ターゲットプラットフォーム(本当に必要な場合はWindowsでUnix用にコンパイルできます)と使用されるコンパイラに依存するマシンコードであることを意味します。異なるコンパイラは、同じソースファイルから異なるマシンコードを生成します。

3
ChrisF

ファイルにはバイナリデータが含まれており、実行可能ファイルを生成するには linker で実行する必要があります。基本的に、名前付きセクション(関数に対応)を持つマシンコード命令の束です。ウィキペディアの「 Object File 」記事から:

コンピュータサイエンスでは、オブジェクトファイルは、マシンコードの名前が付けられた別個のシーケンスの整理されたコレクションです[要出典]。通常、各シーケンスまたはオブジェクトには、関連するデータとメタデータ(たとえば、再配置情報、スタックの巻き戻し情報、コメント、プログラムシンボル、デバッグまたはプロファイリング情報)を伴うホストマシンへの命令が含まれます。通常、リンカは、オブジェクトファイルの一部を組み合わせて実行可能ファイルまたはライブラリを生成するために使用されます。

1
soulmerge

GNUコンパイル環境では、実行可能ファイルとオブジェクトファイルの両方でobjdumpを使用できます。

ご覧のとおり、オブジェクトには、コンパイル済みファイル内で宣言/参照された関数のコードのみが含まれています(ファイルには、scanf呼び出しとprintf呼び出しを含むメイン関数のみが含まれています)。

$ objdump -t scanf_sample.o

scanf_sample.o:     file format pe-i386

SYMBOL TABLE:
[  0](sec -2)(fl 0x00)(ty   0)(scl 103) (nx 1) 0x00000000 scanf_sample.c
File
[  2](sec  1)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00000000 _main
[  3](sec  1)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000000 .text
AUX scnlen 0x91 nreloc 9 nlnno 0
[  5](sec  2)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000000 .data
AUX scnlen 0x0 nreloc 0 nlnno 0
[  7](sec  3)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000000 .bss
AUX scnlen 0x0 nreloc 0 nlnno 0
[  9](sec  4)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000000 .rdata
AUX scnlen 0x54 nreloc 0 nlnno 0
[ 11](sec  0)(fl 0x00)(ty  20)(scl   2) (nx 1) 0x00000000 ___main
AUX tagndx 0 ttlsiz 0x0 lnnos 0 next 0
[ 13](sec  0)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000000 __alloca
[ 14](sec  0)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00000000 _memset
[ 15](sec  0)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00000000 _scanf
[ 16](sec  0)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00000000 _printf

実行可能ファイルでobjdumpを使用すると、さらに多くの関数を見ることができます(オブジェクト内にある関数を除く)。これにより、オブジェクトファイルには、ソースファイルで定義された関数のみが含まれ、他の関数への参照が含まれていることがわかります。これらの参照は、リンクフェーズで解決されます。

リンクコンパイル 、および オブジェクト の詳細をご覧ください。

1
INS