使用objcopy将二进制文件嵌入到elf中可能会导致对齐问题?

时间:2012-01-11 16:32:52

标签: gcc arm alignment elf

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的对齐方式,或者它被破坏了,你根本不应该使用这个方法。

2 个答案:

答案 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对象的精灵档案。