目标文件包含什么?

Vij*_*jay 45 c c++ compilation

在C或C++编译的各个阶段,我知道生成了一个目标文件(即any_name.o文件).这个.o文件包含什么?我无法打开它,因为它是一个二进制文件.

有人可以帮帮我吗?目标文件的内容主要依赖于我们在Unix上使用的编译器吗?

Rod*_*ddy 47

对象文件可以包含很多东西:基本上它是以下列表中的部分或全部:

  • 符号名称
  • 编译代码
  • 常数数据,例如 字符串
  • 导入 - 编译代码引用的符号(由链接器修复)
  • 导出 - 目标文件可用于OTHER对象文件的符号.

链接器将一堆目标文件转换为可执行文件,方法是匹配所有导入和导出,并修改已编译的代码以便调用正确的函数.


kri*_*iss 8

有几种标准化格式(在Unix上使用COFF,ELF),基本上它们是与可执行文件相同格式但是缺少某些信息的变体.链接时将完成这些缺失的信息.

对象文件格式基本上包含相同的信息:

  • 编译产生的二进制代码(用于目标处理器)
  • 程序的那一部分使用的静态数据(如常量字符串等).您可以在BSS(导出数据)和Text(程序不会修改的数据)之间进行更精细的区分.但这对编译器和链接器来说非常重要.请注意,与二进制代码一样,数据也依赖于目标(big-endian,little-endian,32bits,64bits).
  • 这部分程序导出的符号表(主要是函数入口点)
  • 该部分程序使用的外部符号表

当对象链接在一起时,引用外部符号的代码部分将被实际值替换(嗯,仍然过于简单,最后一部分将在加载时运行程序时完成,但这是理念).

目标文件还可能包含更多解析导入和导出所必需的符号信息(对调试很有用).可以使用strip命令删除该信息.


Mat*_*hen 6

使用 file 命令进行此类操作。它是现代 Linux 系统上的ELF对象文件。例如,如果为 32 位 x86 编译。

ELF 32-bit LSB relocatable, Intel 80386, version 1 (SYSV), not stripped
Run Code Online (Sandbox Code Playgroud)

相比之下,动态链接的可执行文件可能如下所示:

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

要查看标题,包括部分名称,您可以使用:

objdump -x any_name.o
Run Code Online (Sandbox Code Playgroud)

拆卸:

objdump -d any_name.o
Run Code Online (Sandbox Code Playgroud)


Shi*_*zou 6

首先,可以打开二进制文件!不要害怕,您只需要合适的工具!作为二进制数据,文本编辑器当然不是正确的工具;一个正确的工具可以是十六进制编辑器,或者像 emacs 这样的高级编辑器,或者是一种工具,而不是简单地以“十六进制”表示“输出”字节,让您独自解释数据,而是知道特定的格式和“在某种程度上正确解释“数据”(例如,GIMP 将 PNG 文件解释为图像并显示它,PNG 分析器将“分解”PNG 部分内的数据,显示告诉您某些字节中的标志等)。

在您的情况下,一般的答案是目标文件包含您编译的代码(和数据),以及链接器所需的所有额外信息,最终更多。

这些信息是如何“组织”的,在某些情况下,“最终更多”由什么组成,这取决于特定的对象格式。一些维基百科链接列出了一些可能性是这个这个这个这个……

其中每一个都可能有分析内容的工具;例如readelf对于ELF,objdump对于几种格式(尝试objdump -i),取决于它是如何编译的。


Chr*_*isF 5

目标文件是编译后的源代码。

这意味着它是机器代码,它依赖于目标平台(如果你真的想要,你可以在 Windows 上为 Unix 编译)和使用的编译器。不同的编译器会从同一个源文件生成不同的机器代码。


Dan*_*uţă 5

首先阅读维基页面.您可以使用objdump来检查这样的文件:)