I’m trying to compile a binary file into a MACH_O object file so that it can be linked it into a dylib. The dylib is written in c/c++.
On linux the following command is used:
ld -r -b binary -o foo.o foo.bin
I have tried various option on OSX but to no avail:
ld -r foo.bin -o foo.o
gives:
ld: warning: -arch not specified
ld: warning: ignoring file foo.bin, file was built for unsupported file format which is not the architecture being linked (x86_64)
An empty .o file is created
ld -arch x86_64 -r foo.bin -o foo.o
ld: warning: ignoring file foo.bin, file was built for unsupported file format which is not the architecture being linked (x86_64)
Again and empty .o file is created. Checking the files with nm gives:
nm foo.o
nm: no name list
The binary file is actually, firmware that will be downloaded to an external device.
Thanks for looking
Here’s the closest translation to the Linux linker command to perform binary embedding with the OSX linker:
foo.binwill be stored in segmentbinary, sectionfoo_bin(both names are arbitrary but chosen to mimic GNU ld for ELF on Linux) of thefoo.oobject.stubis necessary becauseldrefuses to create just a custom segment/section. You don’t need it if you link directly with a real code object.To get data back from the section, use getsectbyname (struct is defined in
mach-o/loader.h):or getsectdata:
(I used it to store text data, hence the stringification via
calloczeroing of size+1 plus blob copying)Warning: Since 10.7, ASLR got stronger and messes badly with
getsect*functions, resulting in segfaults.set disable-aslr offin GDB beforerunning to reproduce EXC_BAD_ACCESS (SIGSEGV) in debug conditions. People had to jump through inordinate hoops to find the real address and get this working again.A simple workaround is to get the offset and size, open the binary and read the data straight from disk. Here is a working example: