I want to compile a bunch of C++ files into raw machine code and the run it with a platform-dependent starter written in C. Something like
fread(buffer, 1, len, file);
a=((*int(*)(int))buffer)(b);
How can I tell g++ to output raw code?
Will function calls work? How can I make it work?
I think the calling conventions of Linux and Windows differ. Is this a problem? How can I solve it?
EDIT: I know that PE and ELF prevent the DIRECT starting of the executable. But that’s what I have the starter for.
There is one (relatively) simple way of achieving some of this, and that’s called "position independent code". See your compiler documentation for this.
Meaning you can compile some sources into a binary which will execute no matter where in the address space you place it. If you have such a piece of x86 binary code in a file and
mmap()it (or the Windows equivalent) it is possible to invoke it from both Linux and Windows.Limitations already mentioned are of course still present – namely, the binary code must restrict itself to using a calling convention that’s identical on both platforms / can be represented on both platforms (for 32bit x86, that’d be passing args on the stack and returning values in EAX), and of course the code must be fully self-contained – no DLL function calls as resolving these is system dependent, no system calls either.
I.e.:
Then
mmap()that file, initialize a function pointer, and(*myblob)(someArgs)may do.If you’re using gcc, the
-ffreestanding -nostdinc -fPICoptions should give you most of what you want regarding the first two, then use objdump to extract the binary blob from the ELF object file afterwards.