What's the difference between the OMF and COFF format? - visual-c++

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.

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.

Related

Why are C/C++ 'obj' files valid only for a specific compiler?

After much struggling with attempting to link a C++ project to a 3rd party static library (.lib), I think I have solved the issue by verifying that I compile my project using the same compiler in which the .lib file was compiled (MSVC11).
Until this point, I assumed all .obj files were equivalent, thus I could take a .lib file (containing various .objs), and use that with any other project I might want to develop in the future. However, this was an incorrect assumption.
So I'm curious as to why (in the context of MSVC) .obj files differ from one version of the compiler to the next. Assuming you're targeting an x86 application, shouldn't the obj files be comprised of the same types of instructions regardless of whether or not you compiled using MSVC11/12/14?
TLDR; Why can't I link a project to an .obj that was created using a different MSVC compiler?
That's because it could be linked to another version of Visual C++ runtime libraries, which is incompatible with the version you are using.
This problem could be even with DLLs if you try to expose C++ objects from it.

How to tell if current OS uses Linux-like or MacOSX-like shared libraries?

I am aware that there are (at least) two radically different kinds of shared-library files on Unix-type systems. One is the kind used on GNU/Linux systems and probably other systems as well (with the filename ending in ".so") and the other used in Mac OS X, and also possibly other systems as well (with the filename ending in ".dylib").
My question is this --- is there any type of test I could do from a shell-script that would easily detect which of these two paradigms the current OS uses for shared libraries?
I'm sure I could find some way to easily deal with this variance --- if only I knew of a simple test I could run from a shell-script that would tell me which type of shared library is used on the current system.
Well, I guess you need to check filetypes of executables on a target platform. You may use file for that (check its output for, say, /bin/ls ). ELF is a most widely used executable type on Linux, while Mach-O is "natively" used in MacOS X.
A note: technically there're other executable types on these systems, say a.out and PEF, and, you guess, those formats have their own dynamic libraries. Frankly speaking Linux has a pluggable support for executable formats and even Win32 .EXEs may be executed "quasi-natively" in Linux (of course, they need an implementation of Win32 API working above a given kernel API, WINE is a such implemetation).
Also if you need to create a dynamically loaded library, then you should use one of those portable build systems (to name a few: GNU autotools, CMake, QMake...). Thus you'll get not only ordinary DLL extension but also linker flags, portable methods of installation/uninstallation and so on...

Options for using MSVC static libraries with MinGW (reimp was unable to convert them)

I work for a company that recently purchased a piece of hardware accompanied by an SDK. Unfortunately, all the SDK libraries were compiled with a Microsoft Visual C++ compiler (I don't know which one) and cannot be used by MinGW (I develop in Code::Blocks using the MinGW C++ compiler).
I've attempted to convert the libraries using reimp (from the MinGW utilities collection), which has worked in the past with static libraries from other vendors, but in this case the converted libraries result in "undefined reference" errors when linked.
The def files generated by reimp for each library during the conversion process don't look very good (they're filled with lines like ??0nameOfFunction##QEAA#AEBV0##Z, while the def files generated during a successful conversion contain lines similar to nameOfFunction#32), so it seems that the vendor's libraries are simply of a type that reimp can't convert.
Are there any other options that would allow me to use these libraries with MinGW? If not, is it reasonable to request that the vendor recompile their libraries with g++ (i.e., is it something they could feasibly do given that the libraries were originally developed using MSVC)?
Any comments or suggestions are appreciated!

16-bit obj files VC++

How do I compile my VC++ project to a 16-bit flat object file for use in my bootloader I am working on?
To my understanding, an object file is technically already "flat" and the linker turns it into the destination executable format. What I want it to be able to obtain that object file and pass that and my assembly code (in obj format) through the linker to create a flat bootloader.
The [guide][1] is not very specific on where the files are located and just says that you use cl.exe, link.exe, and ml.exe (MASM).
The guide uses MASM, but I know how to output object files with NASM. My main problem is the VC++ thing.
The last 16-bit compiler from Microsoft was VC++ 1.52c. It's ancient, and probably not available any more. Even if it was, chances are pretty good that it wouldn't compile any recent code. Just to name a few of its most obvious shortcomings, it had no support for templates, exception handling, or namespaces at all.
I believe most people working on things like that any more use Open Watcom (which isn't exactly up to date either, but still better than VC++ 1.52c).

what is a .sa file for gcc shared library?

I saw an article in http://www.linuxjournal.com/article/1052 where it specifies :
"Shared libraries consist of two basic parts: the stub and the image. The stub library has an extension of .sa. The stub is the library an executable will be linked to."
But another reference http://www.faqs.org/docs/Linux-HOWTO/GCC-HOWTO.html it says
"shared library files (.sa for a.out, .so for ELF) " - Which I understand like .sa is the shared library to use with a.out format, and .so is to use with latest ELF format.
Due to the lack of clarity here , I am asking the question here - what is .sa file ? And what a stub is for?
That article is very old (1995) and is still dealing with pre-ELF (so called a.out) shared libraries.
I forgot the details, but in that prehistoric times, a.out shared libraries where not position independent, so every process had -for example- to load the libc shared library at the same place using the uselib(2) syscall -which is obsolete today- (Today two different processes would mmap(2) it, as a shared ELF object, at various addresses). The .sa file also required conventions for this fixed place. Because of that, making shared libraries was really a nightmare: the fixed address segment[s] that they occupied was to be conventionally defined for the entire system or distribution!
But you really should not care today in 2012 , unless you are interested by history (and then you have to dig several old historical documents which might be difficult to find). All distributions, even some quite old one (e.g. from 2004), are using the ELF format which enable each process to mmap its shared libraries as it wish.
Today, you can explore with /proc/1234/maps or /proc/1234/smaps the memory map of process of pid 1234, and you can easily understand that ELF shared objects are mapped at different places. Read also about ASLR
They're probably both correct but in their own context.
The first article dates from 1995 and that was about when Linux adopted ELF in the mainstream (it existed mid 94 but you had to work hard to get it). In fact, it even discusses the fact that ELF is a relative newcomer:
Even though ELF (the executable and linking format designed for Unix SVR4), which makes creating shared libraries trivial, is just over the horizon, the current a.out DLL shared libraries will probably need to be supported for some time.
So it's probably correct in that all it knew or cared about at the time was the a.out format.
The HowTo is dated somewhat later as 1999 and discusses the differences between a.out and ELF so I would consider it a more reliable source. At that point, ELF had been mainstream for several years.
Of course, that's a relative comparison. The more reliable source is still well over a decade old, talking about gcc 2.7 as if it's the latest and greatest whereas, in fact, we'll well advanced to 4.6.
You may want to consider finding something a little more recent.

Resources