使用 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 链接器脚本包含二进制文件的主要内容,如果未能解决你的问题,请参考以下文章