How do I embed the contents of a binary file in an executable on Mac OS X?

▼魔方 西西 提交于 2019-12-03 16:09:04

During the link phase, pass the arguments -sectcreate <segname> <sectname> <file> to the linker. If you're driving the linker via an invocation of the compiler, which is pretty common, you'd pass it as -Wl,-sectcreate,<segname>,<sectname>,<file>.

You'd make up segment and section names.

You would use the getsectdata() function along with _dyld_get_image_vmaddr_slide() to get a pointer to the data at runtime.

zneak

As evidenced in this other question about objcopy, another way to include a binary file into an executable is to use the .incbin assembler directive. This solution has two main advantages over objcopy: the developer is in control of the symbol names (objcopy appears to have a fixed scheme to name them), and, well, it doesn't require objcopy.

The solution also has advantages over the linker-based -sectcreate solution. It's cross-platform and accessing the data is much, much more straightforward.

I'm using this Xcode build rule script to generate the file to be included and an assembly file with the .incbin directive:

my_generation_tool -o $DERIVED_FILE_DIR/$INPUT_FILE_NAME.out $INPUT_FILE_PATH

export AS_PATH=$DERIVED_FILE_DIR/$INPUT_FILE_NAME.out.s

echo "\t.global _data_start_$INPUT_FILE_BASE" > $AS_PATH
echo "\t.global _data_end_$INPUT_FILE_BASE" >> $AS_PATH
echo "_data_start_ $INPUT_FILE_BASE:" >> $AS_PATH
echo "\t.incbin \"$INPUT_FILE_NAME.out\"" >> $AS_PATH
echo "_data_end_$INPUT_FILE_BASE:" >> $AS_PATH

Then, given a file "somefile.gen" that is processed with this rule, the assembly will look like:

    .global _data_start_somefile
    .global _data_end_somefile
_data_start_somefile:
    .incbin "somefile.gen.out"
_data_end_somefile:

The data can be accessed in C using the data_start_somefile and data_end_somefile symbols (the macOS linker prefixes C names with a spurious _, that's why the assembly file has them):

extern char data_start_somefile, data_end_somefile;

for (const char* c = &data_start_somefile; c != &data_end_somefile; ++c)
{
    // do something with character
}

The answer on the other thread has more bells and whistles that some people may find useful (for instance, a length symbol).

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!