stackoverflow和其他地方有很多帖子详细介绍了如何将二进制blob嵌入到elf二进制文件中。
Embedding binary blobs using gcc mingw
和
C/C++ with GCC: Statically add resource files to executable/library
是最完整的答案。
但是有一个可能没有人提到的问题。这是一个快速的foo.txt转换为foo.o:
$ objdump -x foo.o
foo.o: file format elf32-i386
Sections:
Idx Name Size VMA LMA File off Algn
0 .data 0000000d 00000000 00000000 00000034 2**0
CONTENTS, ALLOC, LOAD, DATA
SYMBOL TABLE:
00000000 l d .data 00000000 .data
0000000d g .data 00000000 _binary_foo_txt_end
0000000d g *ABS* 00000000 _binary_foo_txt_size
00000000 g .data 00000000 _binary_foo_txt_start
现在,我并没有真正理解所有这些输出 - 是否有这些东西的文档?我猜大部分都很明显“g”是全球性的,“l”是本地等等......
突出的是.data段的对齐设置为0.这是否意味着我认为这意味着什么?即:当涉及链接时,链接器将“啊是啊,无论在哪里......”
如果您嵌入了char数据或正在使用x86,那么您将永远不会注意到。但是如果你嵌入int数据,或者就像我正在做的那样,在ARM上嵌入16位和32位数据,那么你可以随时获得一个对齐陷阱。
我的直觉是,这意味着objcopy需要另一个选项来指定二进制blob的对齐方式,或者它被破坏了,你根本不应该使用这个方法。
答案 0 :(得分:4)
为了回答我自己的问题,我断言在这种情况下objcopy被破坏了。我相信使用装配可能是使用Gnu的最佳方式。不幸的是我现在是linux机器,所以不能正确测试这个,但我会把这个答案放在这里以防万一有人发现它或想要检查:
.section ".rodata"
.align 4 # which either means 4 or 2**4 depending on arch!
.global _binary_file_bin_start
.type _binary_file_bin_start, @object
_binary_file_bin_start:
.incbin file.bin
.align 4
.global _binary_file_bin_end
_binary_file_bin_end:
下划线是用C / asm互操作性来惹恼自己的传统方式。换句话说,它们在Windows下用MS / Borland编译器消失了。
答案 1 :(得分:4)
创建链接描述文件" lscript.ld"
MEMORY
{
memory : ORIGIN = 0x00000000, LENGTH = 0x80000000
}
SECTIONS
{
.data (ALIGN(4)) : {
*(.data)
*(.data.*)
__data_end = .;
} > memory
.text (ALIGN(4)) : {
*(.text)
*(.text.*)
__text_end = .;
} > memory
_end = .;
}
链接您的文件:
gcc -Wl,-T -Wl,lscript.ld -o linked_foo.elf foo.o
查找链接中添加的所有无关内容:
objdump -x linked_foo.elf
再次进行Objcopy,删除额外的东西:
objcopy --remove-section ".init_array" (repeat as necessary) --strip-all --keep-symbol "_binary_foo_txt_start" --keep-symbol "_binary_foo_txt_end" --keep-symbol "_binary_foo_txt_size" linked_foo.elf final_foo.elf
这会让你获得2 ** 2对象的精灵档案。