Now that all major 3 OS are supported, I can say that the Mac OS X file ABI and function call ABI are really the most complicated one to support from scratch, the Windows one (PE/COFF) being the simplest (with its own set of oddities, but simpler) and Linux’s ELF somewhere in between. Among the issues we had to identify and deal with:
Stack alignment on 16 bytes constraint at the point of every library call (meet with the infamous “gate keeper” code causing segfaults and bus errors on misaligned calls)
Extra stack entry for each BSD system call.
Working around dynamically linked libraries info extraction that need to be copied from each library header to the generated executable image. This could have prevented cross-compilation.
The need for direct CALL opcode in the generated IA-32 code instead of indirect ones used for PE and ELF library function callings.
As you can see, it is fully functional and all unit tests are passing!
A couple of notes about usage:
The library you declare in #import definition needs to be located in /usr/lib/ or else, you need to provide a full path to the library.
The file emitter should support up to 255 imported libraries (Mach-O limit), but it has been tested only with one so far (libc.dylib), so if you have anything odd happening with more than one imported library, please fill a bug report in github’s tracker, or post a message to the mailing-list.