将部分注入GNU ld脚本; binutils版本之间的脚本兼容性。

时间:2011-07-29 19:14:58

标签: c linker ld binutils

我正在构建问题How to collect data from different .a files into one array? How to keep sections in .a files with ld script?之类的东西,即在链接时从不同目标文件中元素组成的数组。

在我的例子中,有几个数组,每个数组都进入它自己的部分,.ld_comp_array_ *,其中*匹配数组的名称。然后我使用ld --verbose获取默认的链接描述文件,并通过将所有这些部分(排序,以便不同数组的元素不会混合)修改它到输出部分:

KEEP (*(SORT_BY_NAME(.ld_comp_array*)))

一切正常。

然后事情变得更复杂了,因为使用此功能的应用程序可以为各种平台构建 - 到目前为止,我已成功尝试AVR Xmega作为目标平台,以及Windows 32位和Linux用于单元测试的32位和64位,列表是开放的(不久的将来可能会添加新平台)。

但是,对于每个特定平台,默认链接描述文件与其他平台不同,目前我手动插入.ld_comp_array *部分 - 是否有可能以某种方式自动执行?我想到的唯一解决方案是解析默认脚本并粘贴上面的输入节描述,但这似乎太重了。

如果没有相对简单的解决方案,我可以手动完成它,但我不确定从本地版本的ld获取的默认脚本是否可能在不同版本的binutils上中断。任何人都可以澄清这是否安全吗?

如果它可以自动完成,是否可以将输入节规范直接“注入”.text部分,假设数组应该是“不可变的”?

1 个答案:

答案 0 :(得分:16)

我找到了一个令人满意的解决方案。 GNU ld具有INSERT选项,该选项使外部支持的脚本不会覆盖默认脚本,而只是在相对于默认脚本中存在的某个部分的位置添加新部分。

所以在我的例子中,传递给链接器的脚本可能很简单:

SECTIONS
{
  .rodata.ld_comp_array :
  {
    *(SORT_BY_NAME(.ld_comp_array*))
  }
}
INSERT AFTER .rodata;

有关INSERT选项的更多信息:http://sourceware.org/binutils/docs/ld/Miscellaneous-Commands.html#Miscellaneous-Commands