OMF格式和COFF格式有何区别?

14

最近我在维护一个使用VC++ 6.0编写的遗留项目。该代码使用了许多这个编译器的独特特性,因此将其移植到更高版本的编译器中变得异常艰巨。

项目中有数千行代码,其中包括四个汇编文件。由于某种我不理解的原因,MASM615和TASM都无法编译它们(会出错),但是我有目标文件。然而,当我链接库时,我收到一条消息

警告 LNK4033:从OMF格式转换为COFF格式的对象

库按预期工作,但我一直在想这些二进制格式之间的区别,或者我是否应该从这种转换中期待某些问题。


2
请查看http://www.iecc.com/linker/linker03.html。 - avakar
1
@avakar:为什么不把那个链接放到一个合适的答案里呢? - xtofl
@avakar的链接已经失效,但是可以在archive.org上找到。 - jrh
1个回答

18

自个人电脑时代诞生以来,一直到微软的Win32编程工具问世前,几乎所有的个人电脑编译器都使用英特尔目标模块格式(OMF)标准生成目标文件。后来,英特尔推出了386处理器和32位保护模式,他们也扩展了OMF规范以支持32位,形成了“OMF-386”,并成为大多数个人电脑保护模式环境的标准。与此同时,最初的Windows NT开发团队不仅设计代码支持英特尔处理器,还要支持其他厂商的处理器。微软NT团队选择了更便携的对象模块格式,称为通用对象文件格式(COFF),该格式派生自UNIX System V的官方目标代码格式。COFF目标模块后来成为所有微软Win32开发工具的事实标准,并且由于其格式与Win32的本地可执行文件格式Portable Executable文件非常接近(使用COFF格式链接器创建32位EXE或DLL所需的工作量比使用OMF格式文件少得多),因此它具备优势。

就像有OMF格式和COFF格式的目标文件(.obj),还有OMF格式和COFF格式的库文件(.lib)。幸运的是,库基本上只是包含对象文件的集合,以及一些头文件信息,用于让链接器从库中确定要使用哪些对象文件。然而,为了增加难度,OMF和COFF都使用相同的文件名扩展名.obj和.lib来引用这两种不同类型的目标和库文件格式(因此您不能仅通过文件名扩展名判断目标模块或库文件是OMF还是COFF)。

混合使用来自不同编译器供应商的目标文件和库文件存在问题,因为一些供应商支持COFF,另一些供应商使用OMF,还有少数可以处理两者。例如,Borland仍然使用OMF目标文件和库文件,而Microsoft的32位编译器生成COFF格式文件。Watcom C/C++ v11.0在编译和链接Windows应用程序时似乎更喜欢使用COFF,但是为了与其DOS4GW 32位保护模式DOS扩展器一起使用,会生成OMF目标文件。此外,Microsoft MASM 6.13默认生成OMF文件,但可以通过/coff开关发出COFF目标文件。
当需要链接不同格式的文件时,不同的链接器会做出不同的处理。例如,Microsoft Visual C/C++链接器设计用于COFF格式目标文件和库文件,但如果必要,它将尝试将OMF目标文件转换为COFF文件。这在某些情况下有效,但不幸的是,Microsoft LINK并不支持所有OMF记录类型,因此在许多情况下,给定OMF格式目标文件时链接器仍可能失败。另外,虽然Microsoft LINK尝试为OMF目标文件提供一些支持,但它将拒绝处理任何OMF格式库文件。其他链接器(如Borland的TLINK)专为OMF目标文件设计,类似地,它也会拒绝使用COFF格式目标或库文件。一些DOS扩展器和嵌入式系统供应商(如Phar Lap)提供自己的链接器,支持OMF和COFF,从而使您有选择的余地。
总之,混合使用OMF和COFF目标和库文件类型可能会很麻烦(加上链接器的密密麻麻的错误信息并没有帮助)。除非您的链接器专门支持它,否则应坚持使用编译器/链接器/平台推荐的目标和库文件格式,并避免混用OMF和COFF文件。

底线似乎是他的链接器进行了转换。它没有生成错误。 - xtofl
但并非所有的转换都能顺利进行。如果出现任何运行时错误或函数失败,首先要查看此库、对象或库中的对象。当然,也可能一切都很好。 - kingchris
所有的链接器都必须在最后创建一个PE-COFF可执行文件才能在Windows平台上运行吗?也就是说,在链接过程之后,最终生成的可执行文件是否可以包含特定于另一种对象格式(例如OMF)的数据和结构?如果可以,那么它是如何工作的?(或者说它可以如何工作?) - greatwolf
1
不完全是这样。COFF的一些位可以直接进入PE格式。请阅读主问题下avakar提供的链接。那个链接比我的简短复制粘贴更好。但是在阅读该文章时,您必须让所有神经元都处于在线状态。下载并慢慢阅读它。我学到了很多东西。 - kingchris

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接