用法之间的区别。 a.out,.ELF,.EXE和.COFF

时间:2013-06-27 06:42:05

标签: linker executable elf coff

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

MY CONFUSION

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

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

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

问题

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

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

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

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

  4. 根据问题1.(可能还有2个)我是否需要使用带有目标代码的符号表(例如.LUM或.MAP文件)?调试符号中的符号,并在不同机器上重新托管可执行文件/目标文件时使用它们。

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

    更新

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

1 个答案:

答案 0 :(得分:13)

  

我主要是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默认值,但是如果您在file上运行a.out命令,那么'我会发现它是一个ELF文件。 a.out格式很古老,有点“事实上已过时”。

  

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

您已经获得了对象文件的维基百科链接here's the one to "Portable Executable"

  

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

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

  

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

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

  

根据问题1.(可能还有2个)我是否需要使用带有目标代码的符号表(例如.LUM或.MAP文件)?调试符号中的符号,并在不同机器上重新托管目标文件时使用它们。

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