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
use a Hex editor to create the file. that way you get actual binary data instead of encoded text that consists of 1 and 0 characters. a web search for osx hex editor turns up quite a few options. Depending on your choice of products, you may have to enter the data in Hex, but that will still result in a binary file.
Mac C compilers compile C code into an executable. This executable can be run directly to run the C code. Clang and GCC(GNU Compiler Collection) are the common compilers that are used to compile C code.
If your Mac correctly interprets the BIN file extension and recognizes the file as MacBinary, it will be identified accordingly in list-view Finder windows. If your Mac doesn't immediately decompress a BIN file, right-click on the file and choose "Open With." Select "Archive Utility. app" from the list of options.
MacBinary is a file format that combines the two forks of a classic Mac OS file into a single file, along with HFS's extended metadata. The resulting file is suitable for transmission over FTP, the World Wide Web, and electronic mail.
Here's the closest translation to the Linux linker command to perform binary embedding with the OSX linker:
touch stub.c
gcc -o stub.o -c stub.c
ld -r -o foo.o -sectcreate binary foo_bin foo.bin stub.o
foo.bin
will be stored in segment binary
, section foo_bin
(both names are arbitrary but chosen to mimic GNU ld for ELF on Linux) of the foo.o
object.
stub
is necessary because ld
refuses 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
):
#include <mach-o/getsect.h>
const struct section_64 *sect = getsectbyname("binary", "foo_bin");
char *buffer = calloc(1, sect->size+1);
memcpy(buffer, sect->addr, sect->size); // whatever
or getsectdata:
#include <mach-o/getsect.h>
size_t size;
char *data = getsectdata("binary", "foo_bin", &size);
char *buffer = calloc(1, size+1);
memcpy(buffer, data, size); // whatever
(I used it to store text data, hence the stringification via calloc
zeroing 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 off
in GDB before run
ning 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:
// main.c, build with gcc -o main main.c foo.o
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <mach-o/getsect.h>
int main() {
// finding the filename of the running binary is left as an exercise to the reader
char *filename = "main";
const struct section_64 *sect = getsectbyname("binary", "foo_bin");
if (sect == NULL) {
exit(1);
}
char *buffer = calloc(1, sect->size+1);
int fd = open(filename, O_RDONLY);
if (fd < 0) {
exit(1);
}
lseek(fd, sect->offset, SEEK_SET);
if (read(fd, buffer, sect->size) != sect->size) {
close(fd);
exit(1);
}
printf("%s", buffer);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With