使用 GNU ld 链接器脚本包含二进制文件

Posted

技术标签:

【中文标题】使用 GNU ld 链接器脚本包含二进制文件【英文标题】:Include binary file with GNU ld linker script 【发布时间】:2010-09-24 13:33:34 【问题描述】:

我有一个可用的链接器脚本。我想添加另一个数据部分,其内容是直接从文件中提取的(ld 不应该解析它并提取这些部分等等)。我该怎么做?

OUTPUT_FORMAT("elf32-i386")
ENTRY(start)
SECTIONS

  .text 0x100000 : 
    *(.multiboot)
    *(.text)
    *(.code)
    *(.rodata*)
  
  .data : 
    *(.data)
  
  .bss : 
    *(.bss)
  
  kernel_end = .;
  roottask_start = .;
  .data : 

    HERE I WANT TO INCLUDE THE ENTIRE CONTENTS OF ANOTHER (BINARY) FILE

  
  roottask_end = .;

【问题讨论】:

海合会:***.com/questions/4864866/… 【参考方案1】:

您可以尝试使用objcopy 将其转换为您可以链接的普通对象,然后在链接描述文件中引用其符号,就像您对普通对象所做的那样。来自objcopy manual page:

-B bfdarch --二进制架构=bfdarch 将原始二进制输入文件转换为对象时很有用 文件。在这种情况下,输出架构可以设置为 bfdarch。 如果输入文件具有已知的 bfdarch,则此选项将被忽略。 您可以通过引用 由转换过程创建的特殊符号。这些 符号称为_binary_objfile_start_binary_objfile_end_binary_objfile_size。例如您可以将图片文件转换为 一个目标文件,然后使用这些符号在您的代码中访问它。

...其中 objfile 将扩展为输入对象文件的名称。

另请参阅--rename-section 选项。

【讨论】:

bfdarch 文本并非字面意思(也不需要)。如需混淆,请参阅Linking arbitrary data using gcc arm toolchain。【参考方案2】:

您可以将原始文件放在程序集中的单独部分,然后将此部分包含在链接描述文件中。

首先你需要创建模板.S文件,例如。

.section .rawdata
.incbin "blob1.raw"

...并根据需要修改链接描述文件以包含此部分:

.data : 

    *(.rawdata*)


您也可以在这里查看here,了解有关 .S 模板的更多详细信息。

【讨论】:

【参考方案3】:

另一种解决方案是使用BYTE 函数从您的二进制文件中生成包含字节的第二个链接器脚本,然后使用INCLUDE 指令将其包含在前一个链接器脚本中。

您可以通过以下方式使用hexdump 从二进制文件生成脚本:

cat ramelfs | hexdump -v -e '"BYTE(0x" 1/1 "%02X" ")\n"' > ramelfs.ld

然后以这种方式包含它:

SECTIONS 
    .text : 

        /* ... */

        kramelfs = .;
        INCLUDE "ramelfs.ld" ;
        kramelfs_end = .;

       /* ... */
    

【讨论】:

【参考方案4】:
仅使用链接器的另一种方法是使用 TARGET 和 INPUT

    目标(二进制)
    输入 (./my_binary_data.bin)
    输入 (./my_binary_code.bin)
    # 如果需要,在此处添加更多二进制文件
    
    OUTPUT_FORMAT("elf32-i386")
    
    进入(开始)
    
    部分
    
        .text 0x100000:
            *(.multiboot)
            *(。文本)
            *(。代码)
            ./my_binary_code.bin
            *(.rodata*)
        
        。数据 : 
            *(。数据)
        
        .bss:
            *(.bss)
        
        kernel_end = .;
        roottask_start = .;
        。数据 : 
    
            ./my_binary_data.bin
    
        
        根任务结束 = .;
    

【讨论】:

您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center。

以上是关于使用 GNU ld 链接器脚本包含二进制文件的主要内容,如果未能解决你的问题,请参考以下文章

GNU LD 脚本学习笔记

gnu ld/gdb:单独的调试文件。当需要链接的调试信息过多时如何生成调试文件?

ld链接时巨大的二进制大小

来自链接器的奇怪警告(ld)[重复]

binutils工具集

LLD 和链接描述文件