之间的用法差异。 a.out、.ELF、.EXE 和 .COFF

Posted

技术标签:

【中文标题】之间的用法差异。 a.out、.ELF、.EXE 和 .COFF【英文标题】:Usage differences between. a.out, .ELF, .EXE, and .COFF 【发布时间】:2013-06-24 13:07:07 【问题描述】:

不要误会我的意思,看看问题标题 - 我知道它们是什么(可移植可执行文件的格式)。但我的兴趣范围略有不同

我的困惑

我参与重新托管/重新定位最初来自第三方的应用程序。问题是有时目标代码的格式也是 .elf、.COFF 格式,并且仍然显示“可执行和可链接”。

我主要是 Windows 用户,并且知道在编译和汇编 C/C++ 代码时,会得到类似于 .o 或 .obj 的内容。是不可执行的(好吧,我从来没有尝试过执行它们)。但是当您完成链接静态库和动态库并完成构建时,会出现可执行文件。我的理解是,如果需要,您可以使用某种形式的脚本链接该可执行文件或“bash”对其进行测试。

但是,在 Linux(或类似 UNIX 的系统)中,在您编译和汇编 C/C++ 代码之后会有 .o 文件。一旦链接完成,可执行文件就是 a.out 格式(至少在 Linux 的 Ubuntu 发行版中)。它很可能是其他发行版中的 .elf。在我的快速网络搜索中,没有任何来源提到任何关于 .o 文件作为可执行文件的内容。

问题

因此我的问题变成了以下问题:

    可移植可执行文件和目标代码的true定义是什么?

    Windows 和 UNIX 平台如何涵盖相同文件格式(.COFF、.elf)下的可执行文件和目标代码。

    我是否误解了“可链接”?我对“可链接”的解释是编译的目标代码,然后可以“链接”到其他静态/动态链接库。这是一个愚蠢的想法吗?

    基于问题 1。(也许还有问题 2)我是否需要将符号表(例如 .LUM 或 .MAP 文件)与目标代码一起使用?调试符号中的符号以及在不同机器上重新托管可执行文件/目标文件时使用它们。

提前感谢您的正确推动。同时,如有必要,我会继续挖掘和更新问题。

更新

我已经设法从某个地方挖出this :( 对我来说似乎有很多东西要吞下。

【问题讨论】:

【参考方案1】:

我主要是 Windows 用户,并且知道当您编译 C/C++ 代码时,您会得到类似于 .o 或 .obj 的内容。不可执行的

嗯,上次我在 Windows 上编译东西时,编译的结果一个.obj 文件,这正是它的名字所暗示的:它是一个object file。你是对的,它本身不是可执行文件。它包含的机器代码(还没有)包含足够的信息来直接在 CPU 上运行。

但是,在 Linux(或类 UNIX 系统)中,编译 C/C++ 代码后会有 .o 文件。一旦链接完成,可执行文件就是 a.out 格式(至少在 Linux 的 Ubuntu 发行版中)。它很可能是其他发行版中的 .elf。

生活在 90 年代,即 :P 据我所知,没有现代编译器将 a.out 格式作为目标代码的默认输出格式。当没有指定明确的输出文件名时,将目标代码放入名为a.out 的文件中可能是 GCC 的一种误导性默认设置,但如果您在a.out 上运行file 命令,您会发现这是一个ELF 文件。 a.out 格式很古老,有点“事实上已过时”。

可移植可执行文件和目标代码的真正定义是什么?

您已经获得了目标文件的 Wikipedia 链接,here's the one to "Portable Executable"。

Windows 和 UNIX 平台如何涵盖相同文件格式(.COFF、.elf)下的可执行文件和目标代码。

因为 ELF 格式(显然也是 COFF)是这样设计的。那么为何不?毕竟它只是相同的机器代码,在所有编译步骤中使用一种文件格式似乎很合乎逻辑。就像我们不喜欢动态库和独立可执行文件有不同的格式一样。 (这就是 ELF 被称为 ELF 的原因 - 它是一种“可执行可链接格式”。)

我是否误解了“可链接”?

我不知道。从您的问题来看,我不清楚您认为“可链接”是什么。一般来说,这意味着它是一个可以链接的文件,即。 e.图书馆。

基于问题 1。(也许还有 2)我是否需要将符号表(例如 .LUM 或 .MAP 文件)与目标代码一起使用?调试符号中的符号以及在不同机器上重新托管目标文件时使用它们。

我认为这与使用的可执行格式无关。如果要调试,无论如何都要生成调试信息。但是,如果您不需要调试,那么您当然可以随意省略它们。

【讨论】:

我正在更新我的问题(可链接位)。现在应该好多了! @hagubear 抱歉,我完全不明白你的第四个问题。 “使用带有目标代码的符号表”是什么意思?在什么意义上使用? “与目标代码”是什么意思? 另外,在您发布 Object code bit 之前,我已对其进行了“维基”编辑。由于不同的人对同一主题有不同的输入,***有时会被破坏。我比任何书籍或网站都更尊重 ***,因为像您这样的专家用户实际上可以建设性地批评问题范围并分享您对这些问题的知识/理解。因此,我的问题在这里而不是***:) @hagubear 我认为现在我明白了,请参阅编辑。是的,在某些情况下,Stack Overflow 可能比 Wikipedia 更值得信赖。 而且,我还远不是专家 :) 感谢 H2CO3。请注意,我将“编译”修改为“编译和组装”,因为它对目标文件而不是汇编代码有意义。

以上是关于之间的用法差异。 a.out、.ELF、.EXE 和 .COFF的主要内容,如果未能解决你的问题,请参考以下文章

自己动手写一个操作系统——elf 和 bin 文件区别

自己动手写一个操作系统——elf 和 bin 文件区别

自己动手写一个操作系统——elf 和 bin 文件区别

链接器会将哪些类型的符号放入可执行的 ELF 中?

图文并茂 | 例说ELF文件

在用户空间中加载 C 中的 ELF 文件