GNU ld删除部分

问题描述:

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

但是,如果我用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不了解它,但它会导致设备无法正确引导。

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

尝试添加类似:

KEEP(*(.boot)) 
ld链接脚本

告诉链接,以保持.boot部分。

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

我想你想通过--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'. 

链接器将仅从归档中提取解析明确引用的符号所需的那些对象。您的启动代码没有被明确引用,因为它是通过复位向量调用的。

如果你的启动代码包括多个模块,您应该创建一个部分链接对象文件使用LD和-r/--relocatable选项,这将对象合并成一个单一的对象,而不需要解决所有的符号(如主()例如)。这可以用于与应用程序代码的完整链接。如果它只是单个目标文件,那么在任何情况下创建一个存档都没有真正的优势(并且因为您发现它不起作用)。

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

您可以使用ld --whole-archive选项来提取未引用的符号。这ld options page有这对整个归档 --whole归档

对于--whole归档 选项后 命令行中提到的每个存档,包括在 每个对象文件中的链接存档而不是 在档案中搜索所需的 目标文件。这通常用于 将档案文件转换为共享的 库,强制将每个对象包含在生成的共享 库中的 。此选项可能比使用更多 。
从gcc使用此选项时有两点需要注意:首先,gcc不知道关于此选项的 ,因此您必须使用 -Wl,-whole-archive。其次,不要忘记在您的档案列表后使用-Wl,-no-whole-archive ,因为 gcc会将您自己的档案列表 添加到您的链接中,并且您可能不希望这个 标志影响那些好。

也看到堆栈溢出这个问题,uses of whole-archive option

链接时可以使用--whole-archive,但它是一把大象枪。该名男子页声称:

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