【问题标题】:Embedding binary into elf with objcopy may cause alignment issues?使用 objcopy 将二进制文件嵌入到 elf 中可能会导致对齐问题?
【发布时间】:2012-02-08 00:37:18
【问题描述】:

在 stackoverflow 和其他地方有很多帖子详细介绍了如何将二进制 blob 嵌入到 elf 二进制文件中。

Embedding binary blobs using gcc mingw

C/C++ with GCC: Statically add resource files to executable/library

是最完整的答案。

但是有一个可能没有人提到的问题。这是一个转换为 foo.o 的快速 foo.txt:

$ 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,那么您永远不会注意到。但是,如果您在 ARM 上嵌入 int 数据或 16 位和 32 位数据,那么您可能会在任何时候遇到对齐陷阱。

我的直觉是,这意味着要么 objcopy 需要另一个选项来指定二进制 blob 的对齐方式,要么它被破坏了,你根本不应该使用这种方法。

【问题讨论】:

    标签: gcc arm alignment elf


    【解决方案1】:

    为了回答我自己的问题,我断言 objcopy 在这种情况下被破坏了。我相信使用汇编可能是使用 Gnu as 的最佳方式。不幸的是,我现在没有 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 编译器消失。

    【讨论】:

      【解决方案2】:

      创建链接描述文件“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 对齐的 elf 文件。

      【讨论】:

        猜你喜欢
        • 2013-11-25
        • 1970-01-01
        • 1970-01-01
        • 2011-09-24
        • 1970-01-01
        • 2014-05-24
        • 2012-05-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多