OMF 和 COFF 格式有什么区别?
最近我一直在维护一个用 VC++ 6.0 编写的遗留项目。 该代码使用了该编译器的许多独特特性,以至于将其移植到更新的标准编译器已被证明是一项艰巨的任务。
在项目的数千行代码中,有四个汇编文件。 由于某种原因我不明白,MASM615 和 TASM 都无法编译它们(它们发送错误),但我有目标文件。 但是,当我链接库时,我收到一条消息
警告 LNK4033:将对象格式从 OMF 转换为 COFF
该库按预期工作,但我一直想知道这些二进制格式之间有什么区别,或者我是否应该从这种转换中期待一些丑陋的东西。
Recently I've been maintaining a legacy project written in VC++ 6.0. The code uses so many unique characteristics of this compiler that porting it to a more recent standard compiler has proved to be an herculean task.
Among the thousands lines of code in the project, there are four assembler files. For some reason I don't understand, nor MASM615 nor TASM are able to compile them (they send errors), nevertheless I have the object files. However when I link the library I get a message
warning LNK4033: converting object format from OMF to COFF
The library works as expected, but I've been wondering what's the differences between these binary formats, or if I should expect something ugly from this conversion.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
答案摘自“MetaWINDOW FAQ - OMF 与 COFF 对象文件格式.htm”
自 PC 文明诞生以来,直到 Microsoft Win32 编程工具出现为止,几乎所有 PC 编译器都使用 Intel 对象模块格式 (OMF) 生成对象文件) 标准。 后来,Intel 推出了 386 处理器和 32 位保护模式,同时他们还扩展了 32 位的 OMF 规范,导致“OMF-386”成为大多数 PC 保护模式环境的标准。 大约在同一时间,最初的 Windows NT 开发团队也在设计代码,不仅针对英特尔处理器,而且还支持其他供应商的处理器。 Microsoft NT 团队选择了一种更可移植的对象模块格式,称为通用对象文件格式 (COFF),它源自 UNIX System V 的官方对象代码格式。COFF 对象模块后来成为所有 Microsoft Win32 开发工具的事实上的标准,并获得了其优点是格式更接近可移植可执行文件 - Win32 的本机可执行格式(COFF 格式链接器从 COFF 文件创建 32 位 EXE 或 DLL 的工作比从 OMF 格式文件创建 32 位 EXE 或 DLL 的工作少得多)。
正如有 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,但会生成 OMF 目标文件以与其 DOS4GW 32 位保护模式 DOS 扩展器一起使用。 除此之外,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 文件。
Answer nicked out of "MetaWINDOW FAQ - OMF vs COFF Object File Formats.htm"
Since the dawn of PC civilization up until about the time Microsoft Win32 programming tools came along, almost all PC compilers produced object files using the Intel Object Module Format (OMF) standard. Later, Intel introduced 386 processors and 32-bit protected-mode at which point they also expanded the OMF specification for 32-bits, leading to "OMF-386" which became the standard for most PC protected-mode environments. Around this same time, the original Windows NT development team was also designing code, not only for Intel processors, but also to support processors from other vendors. The Microsoft NT team selected a more portable object module format known as Common Object File Format (COFF) derived from the official object-code format for UNIX System V. COFF object modules later became the defacto standard for all Microsoft Win32 development tools, and gained an advantage in being much closer in format to Portable Executable files - the native executable format for Win32 (a COFF-format linker has much less work to create a 32-bit EXE or DLL from a COFF file than from an OMF format file).
Just as there are OMF- and COFF-format object files (.obj's), there are also OMF and COFF format library files (.lib's). The libraries, fortunately, are basically just a collection of the object files, along with some header information that lets the linker determine which object files to use from the library. To make things difficult however, both OMF and COFF use the same file name extensions, .obj and .lib, to reference the two different types of object and library file formats (because of this you can't just look at the file name extension to tell if the object module or library file is OMF or COFF).
The problem with mixing object files and library files from different compiler vendors is that some vendors support COFF, other vendors use OMF, and a few can handle both. Borland, for example, still uses OMF object files and libraries, while Microsoft's 32-bit compilers produce COFF format files. Watcom C/C++ v11.0 seems to prefer COFF when compiling and linking Windows applications, but generates OMF object files for use with their DOS4GW 32-bit protected-mode DOS-extender. Along with this, Microsoft MASM 6.13 produces OMF files by default, but with the /coff switch can emit COFF object files instead.
When it comes time to link files with different formats, different linkers do differnt things. For example, the Microsoft Visual C/C++ linker is designed for COFF format object files and libraries, but will try to convert OMF object files into COFF files if necessary. This works in some cases, but unfortunately Microsoft LINK does not support all OMF record types, so in many situations the linker may still fail when given OMF format object files. Also while Microsoft LINK attempts some support for OMF object files, it will refuse to process any OMF format libraries. Other linkers, such as Borland's TLINK, are designed for OMF object files and will similarly refuse to work with COFF-format object or library files. Some DOS extender and embedded system vendors, such as Phar Lap, provide their own linkers which support both OMF and COFF, giving you a choice.
The bottom line is that mixing OMF and COFF object and library file types can be a mess (plus the cryptic error messages from the linkers don't help). Unless your linker specifically supports it, you should stick with recommended object and library format for your compiler/linker/platform, and avoid mixing OMF and COFF files.