CまたはC++でのコンパイルのさまざまな段階で、オブジェクトファイル(つまり、any_name.oファイル)が生成されることを知っています。この.oファイルには何が含まれていますか?バイナリファイルなので開くことができません。
誰か助けてくれませんか?オブジェクトファイルの内容は、主にUnixで使用するコンパイラに依存していますか?
オブジェクトファイルには多くのものを含めることができます。基本的には、以下のリストの一部またはすべてです。
リンカは、すべてのインポートとエクスポートを照合し、コンパイルされたコードを修正して正しい関数が呼び出されるようにすることで、オブジェクトファイルの束を実行可能ファイルに変換します。
いくつかの標準化された形式(COFF、UnixのELF)があります。基本的に、それらは実行可能ファイルに使用されるものと同じ形式のバリアントですが、一部の情報が欠落しています。これらの欠落情報は、リンク時に完成します。
オブジェクトファイル形式には、基本的に同じ情報が含まれています。
オブジェクトが一緒にリンクされると、外部シンボルを参照するコードの部分は実際の値に置き換えられます(それでもまだ単純化されすぎているため、プログラムの実行時にロード時に行われる最後の部分がありますが、それは考え)。
オブジェクトファイルには、インポートとエクスポートの解決に厳密に必要なシンボル情報がさらに含まれている場合があります(デバッグに役立ちます)。その情報はstripコマンドを使用して削除できます。
このようなことには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
まず、バイナリファイルを開くことができます!怖がらないでください、ちょうどいいツールが必要です!バイナリデータであるため、テキストエディターはもちろん正しいツールではありません。適切なツールは、16進エディタ、emacsのような高度なエディタ、または単に「16進」表現でバイトを「出力」する代わりに、データの解釈をあなたに任せ、その特定の形式と「あるレベルでデータを適切に解釈します(たとえば、GIMPはPNGファイルを画像として解釈して表示し、PNGアナライザーはPNGセクション内のデータを「分解」して、特定のバイトでフラグを示します...など)。
あなたの場合、一般的な答えは、オブジェクトファイルにはコンパイルされたコード(およびデータ)に加えて、リンカが必要とするすべての追加情報が含まれ、最終的にはそれ以上になるということです。
これらの情報がどのように「編成される」か、場合によっては「最終的にはより多く」が何で構成されるかは、特定のオブジェクト形式によって異なります。いくつかの可能性をリストしたウィキペディアのリンクには、 this 、 this 、 this 、 this ...
これらのそれぞれには、コンテンツを分析するためのツールがあります。例えばELFの場合はreadelf
、いくつかの形式の場合はobjdump
(objdump -i
を試してください)コンパイル方法によって異なります。
オブジェクトファイルはコンパイルされたソースです。
これは、ターゲットプラットフォーム(本当に必要な場合はWindowsでUnix用にコンパイルできます)と使用されるコンパイラに依存するマシンコードであることを意味します。異なるコンパイラは、同じソースファイルから異なるマシンコードを生成します。
ファイルにはバイナリデータが含まれており、実行可能ファイルを生成するには linker で実行する必要があります。基本的に、名前付きセクション(関数に対応)を持つマシンコード命令の束です。ウィキペディアの「 Object File 」記事から:
コンピュータサイエンスでは、オブジェクトファイルは、マシンコードの名前が付けられた別個のシーケンスの整理されたコレクションです[要出典]。通常、各シーケンスまたはオブジェクトには、関連するデータとメタデータ(たとえば、再配置情報、スタックの巻き戻し情報、コメント、プログラムシンボル、デバッグまたはプロファイリング情報)を伴うホストマシンへの命令が含まれます。通常、リンカは、オブジェクトファイルの一部を組み合わせて実行可能ファイルまたはライブラリを生成するために使用されます。
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を使用すると、さらに多くの関数を見ることができます(オブジェクト内にある関数を除く)。これにより、オブジェクトファイルには、ソースファイルで定義された関数のみが含まれ、他の関数への参照が含まれていることがわかります。これらの参照は、リンクフェーズで解決されます。