链接器脚本 – 将一个部分放在内存区域的末尾

我已经广泛搜索了如何做到这一点并未能得出答案。

我的内存布局如下:

Fake Address | Section 0 | text 7 | relocate 15 | bss 23 | stack 

在堆栈的末尾我放置堆。 它正在成长,堆栈是我正在使用的ARM芯片的完全下降堆栈。

现在,我想要做的是放置一个部分,让我们称之为.persist ,进入我的ram内存。 我希望它驻留在RAM的最后,我想将其编程到我的链接器脚本中。 但是,此.persist部分的大小不是由我定义的,而是由编译器根据它包含的符号计算的。

到目前为止,我还没有想出一个好办法。 因为我知道RAM起始地址和SIZE,如果我知道部分大小,那么计算部分需要去的位置是微不足道的。 但是,根据GNU链接器文档(第74页),它似乎是:

SIZEOF(section)如果已分配该部分,则返回指定部分的大小(以字节为单位)。 如果在评估此部分时尚未分配该部分,则链接器将报告错误。

所以我无法计算出链接器脚本中该部分的大小(因为我想在放置它/分配之前计算大小)。

有谁知道这样做的好方法?

通过连接两个步骤,我能够完成类似的事情。 首先,我将有问题的部分编译为自己的目标文件。 在我的例子中,我有一个从汇编文件生成的元数据部分。 gcc -c会将源代码编译为目标文件,但不会链接它们。

 gcc -c metadata.s -o metadata.o 

您还可以构建整个程序,然后使用objcopy仅提取相关部分。

 gcc -c main.cc -o main.o objcopy --only-section=.metadata main.o metadata.o 

现在我构建并链接程序的其余部分,并在链接器的输入中包含目标文件。

 gcc metadata.o ../main.o -o Program.elf -T linkerscript.ld 

链接器从目标文件中读取.metadata部分,我可以在链接描述文件中引用它的大小。

我有类似的问题,我这样做了

 /* heap section */ .heap (NOLOAD): { . = ALIGN(8); _sheap = .; . = . + HEAP_SIZE; . = ALIGN(8); _eheap = .; } > ram _ram_end_ = ORIGIN(ram) + LENGTH(ram) -1 ; _stack_size = _ram_end_ - _eheap ; /* stack section */ .stack (NOLOAD): { . = ALIGN(8); _sstack = .; . = . + _stack_size; . = ALIGN(8); _estack = .; } > ram .LastSection (NOLOAD): /* for test in dump file */ { . = ALIGN(8); } > ram 

我想要做的是放置一个部分,让我们称之为.persist,进入我的ram记忆。 我希望它驻留在RAM的最后,我想将其编程到我的链接器脚本中。

链接器脚本具有称为位置计数器的特殊变量,它允许通过在地址空间中创建间隙或孔来修改当前地址,以及部分或符号的大小或地址。

您可以在特定位置强制执行部分。

例如,在此Red Hat GNU Linker文档页面中 ,您可以将.data部分定义为从地址0x8000000开始:

 SECTIONS { . = 0x10000; .text : { *(.text) } . = 0x8000000; .data : { *(.data) } .bss : { *(.bss) } }