I know that a OBJ file produced after compilation of C/C++ source code in any standard compiler generates OBJ file, which later LINKed with the rest of the required libraries to form the EXEcutable file. I want to know the format/structure of the OBJ file. Please go ahead.
C++ Builder (and Delphi) use OMF format obj files. See this wikipedia link for details.
Additional information: Microsoft Visual C++ use an incompatible COFF, that's why C++ Builder have a utility to convert them.
See also: What's the difference between the OMF and COFF format?
the .obj file is a format used by Microsoft Compilers and is described in the (Common Object File Format) COFF spec
other compilers use different formats to store object code, e.g. ELF on Linux
Under windows, it'd be a COFF object. Google this file format for a spec. They are linked to produce a PE.
Related
I've been learning low-level stuff for a while now and I'm quite familiar with PE files and how they work. But I've been unable to find any documentation of their precursor .o files. I'm looking for a deep-dive on the actual byte-by-byte structure of them.
What does the format of .o files depend on? Is it even platform specific at all? Perhaps compiler-specific? Where can I find documentation on the file format of .o files? Mostly interested in Windows.
.o files as produced by GCC and LLVM when using Windows (MinGW) are COFF files (see https://wiki.osdev.org/COFF). On certain other platforms the ELF format is used.
The Windows PE format (used for .dll and .exe files) is actualy a subset of the COFF format.
I'm searching for a C or C++ library which can load and link obj files (doesn't matter if ELF or obj) dynamicly at runtime. I spend some time searching for such library, but my results weren't successful.
What I tried:
LLVM:
Currently my best solution! I used Clang to generate .obj files in the bytecode format of LLVM and used its JIT functions to dynamic load and execute the function. But, the LLVM is huge and my PC at home hasn't the power to compile the complete LLVM just for the JIT. Also I encountered some problems with relocation overflows or not implemented relocation types.
libjit:
I read, that it can load .elf files and link them too. But sadly, I couldn't compile it for windows, so I couldn't try.
Nanojit and NativeJit:
It seems like they don't support JITting an object file.
So... What can I do? Do I have to stick around with the LLVM? Are there any alternatives?
I suppose that an analogy that can be taken as a 1st approach is that the .bc is similar to an .o (or .obj) file in that it is just the translation of C++ code to an intermediate language, and tht it can contain references to functions not defined in it, to be searched in libraries.
And that the JIT-ted code is similar to a DLL, in the sense that it will be linked dynamically to the executable where it will run in.
You need not to compile LLVM -- you can download the binaries for LLVM and assorted utilities (like clang) from LLVM Download Page
Are C++ Lib Files binary, or just some sort of container, like a zip file, which contains all of the binary files?
I ask, because I'm curious if I can open a library file (.lib) to get more information about what files are inside of it, similar to how you can open a jar file and look through it in a human readable way.
I ask, because I'm adding some libraries to my lib path and would prefer to know if the lib files contain the classes I'm trying to reference.
As far as I know, a library file is pure binary. So it's impossible to actually 'see' it's contents like a zip file.
If you got hold of some .lib files then it's probable it also came with documentation that explains it's functionality. That would be a good place to check if your classes are present in the library.
EDIT: This question describes a lib file inspector called dumpbin, might be what you need.
A lib file contains the compiled binary of all of the compilation units that are provided by the library. Since you have tagged C++Builder, I assume you have OMF-libraries. You can easily get quite a lot of information out of these, for example all function signatures in the library.
C++Builder ships with a tool called TDump that prints contents of the library in human-readable form. It's located in the bin-directory under the C++Builder installation directory.
The example below shows you how to use TDump to dump contents of a library from the command line:
"C:\Program Files\Embarcadero\RAD Studio\10.0\bin\tdump.exe" library.lib > library-dump.txt
You can find each object module in the library by searching the output for "THEADR". After the THEADR-line you will have a list of all of the dependency files (basically includes) used when the object was compiled. After the dependencies there are the symbols, including demangled function signatures.
In first 2 pages, layout diagram of PE executable and COFF format is given.
So, my question is,
I assume windows object files and executables are in COFF format, SO WHAT IS PE EXECUTABLE FORMAT?
Sham
Microsoft PE and COFF Specification:
This specification describes the structure of executable (image) files and object files under the Windows family of operating systems. These files are referred to as Portable Executable (PE) and Common Object File Format (COFF) files, respectively.
Is there any way to convert COFF library (lib file) to OMF library for using with C++Builder6 ? This coff is not just import library, it conatians some code.
When I try to convert it using borland's coff2omf.exe, I get 1KB file from 15KB file.
Instead of DigitalMars converter, you may use the Object file converter -- objconv -- available at agner.org/optimize
This utility can be used for converting object files between COFF/PE,
OMF, ELF and Mach-O formats for all 32-bit and 64-bit x86 platforms.
Can modify symbol names in object files. Can build, modify and convert
function libraries across platforms. Can dump object files and
executable files. Also includes a very good disassembler supporting
the SSE4, AVX, AVX2, AVX512, FMA3, FMA4, XOP and Knights Corner
instruction sets. Source code included (GPL).
This is a great site for low-level optimization, and there are a lot of useful information in the associated manual PDF file, about the library formats across several platforms.
It's fairly typical for an OMF object file to be a lot smaller than an equivalent COFF object, so what you're getting may well be valid.
If you find that it's really not, you can probably break the lib file into individual object files, disassemble the object files, re-assemble them to OMF object files, and put those together into an OMF lib file.
This is rather late, but if anyone is looking for an answer, you can checkout COFFIMPLIB from DigitalMars. COFF2OMF is available at the same site, but it looks like that's older.
It may be worth noting that in newer versions of Delphi (>= XE2), the compiler accepts COFF as well as OMF. It's probably also true for C++ Builder. The 64 bit compilers use only COFF.
See here for more informations about linking COFF.
Integrating Delphi (omf) and Ada (gcc, coff) required lots of effort until I've given up doing it in a single exe.
I honestly tried to disintegrate gcc rtl and ada rtl .a (coff libraries) into lots of .o (objects), convert them via coff2omf (there were DMD coff2omf and iirc another convobj or so). Some of the coff .o failed to be converted to .obj so I can't say if it was a reliable way at all.
Assembler level conversion is not so simple when it takes to exceptions and other deep details.
It's a pity I haven't tried a tool named
ftp://ftp.styx.cabel.net/pub/UniLink/
It's not obvious, but UniLink can probably be used to achieve the goal. One of its targets is C++ Builder package (both dynamic and static). unilink -Tpp -GI should do the trick