GNU ld删除部分

时间:2010-04-21 11:27:22

标签: linker embedded arm ld gas

我正在为基于ARM-Cortex M3的设备编写启动脚本。如果我编译汇编程序启动脚本和C应用程序代码,然后组合目标文件并将它们传输到我的设备,一切正常。

但是,如果我使用ar创建存档(libboot.a)并将该存档与C应用程序组合,则会出现问题:

我已将启动代码放在一个部分中:

    .section    .boot, "ax"
    .global     _start

_start:
    .word       0x10000800  /* Initial stack pointer (FIXME!) */
    .word       start
    .word       nmi_handler
    .word       hard_fault_handler
    ... etc ...

我发现ld从最终的二进制文件中剥离了这个(“boot”部分不可用)。这是很自然的,因为ld不知道它有什么依赖性,但它会导致设备无法正确启动。

所以我的问题是:强制包含此代码的最佳方法是什么?

5 个答案:

答案 0 :(得分:10)

尝试添加以下内容:

KEEP(*(.boot))
<{1>}链接器脚本中的

告诉链接器保留ld部分。

但是,我不确定这是否足以导致.bootld部分中的归档中提取任何对象 - 它可能根本不考虑对象,除非某些该对象中的符号导致它被拉入。如果这是一个问题,请将.boot指定为入口点(在ld命令行上使用_start或在链接器中使用-e _start脚本)可能是解决方案。

答案 1 :(得分:3)

我认为您希望将 - no-gc-sections 选项传递给链接器。来自GNU ld documentation

--gc-sections
--no-gc-sections

Enable garbage collection of unused input sections.

`--gc-sections' decides which input sections are used
by examining symbols and relocations. The section
containing the entry symbol and all sections containing symbols
undefined on the command-line will be kept, as will sections
containing symbols referenced by dynamic objects.
Note that when building shared libraries, the linker must
assume that any visible symbol is referenced. Once this initial
set of sections has been determined, the linker recursively marks
as used any section referenced by their relocations.
See `--entry' and `--undefined'.

答案 2 :(得分:2)

链接器仅从存档中提取解析显式引用符号所需的对象。您的启动代码未明确引用,因为它是通过重置向量调用的。

如果您的启动代码包含多个模块,则应使用ld和-r / --relocatable选项创建部分链接的对象文件,这会将对象组合到单个对象中而无需解析所有符号(例如main())。然后,可以将其与您的应用程序代码一起使用。如果它只是一个目标文件,那么在任何情况下创建存档都没有真正的优势(并且你发现它不起作用)。

请注意,传统上GNU C运行时启动是在一个名为crt0.o(不是存档)的文件中提供的,可能是出于同样的原因。

答案 3 :(得分:2)

你可以在链接时使用--whole-archive,但它是一把大象枪。该手册页声称:

  

对于--whole-archive选项后命令行中提到的每个存档,请在链接中包含存档中的每个目标文件,而不是在存档中搜索所需的目标文件。

答案 4 :(得分:1)

您可以使用ld --whole-archive选项引入未引用的符号。这个ld options page有整个档案 --whole-archive

  

对于上面提到的每个档案   --whole-archive之后的命令行   选项,包括每个目标文件   链接中的存档,而不是   在存档中搜索所需的   目标文件。这通常用于   将存档文件转换为共享文件   库,强迫每个对象   包含在结果中   图书馆。可以使用此选项   比一次       从gcc使用此选项时的两个注意事项:首先,gcc不知道   关于这个选项,所以你必须使用   轮候册,-whole归档。其次,不要忘记使用-Wl,-no-whole-archive   在您的档案列表之后,因为   gcc将添加自己的档案列表   到你的链接,你可能不想要这个   标志也影响那些。

另请参阅有关堆栈溢出的问题,uses of whole-archive option