【发布时间】:2021-04-27 02:07:54
【问题描述】:
我正在开发一个 Arm 裸机应用程序,我已经用 NOLOAD 标记了一些部分。根据Understanding linker script NOLOAD sections in embedded software
中的解释,我希望生成的 ELF 文件没有这些部分有可加载的段(程序头),但确实有。
这是正确的吗?为什么这些部分在 ELF 文件中标记为可加载?
由于链接器仍在将数据放在.bss 中,加载程序应该如何知道不应该加载这些部分?还是我错过了“加载”的含义,因为NOLOAD 仅对 initialized 符号有意义(通常会放入 .data)?
这是我的链接器脚本的一部分:
.bss (NOLOAD) :
{
. = ALIGN(4);
__bss_start__ = .;
*(.bss_begin .bss_begin.*)
*(.bss .bss.*)
*(COMMON)
*(.bss_end .bss_end.*)
. = ALIGN(4);
__bss_end__ = .;
} >DRAM
.noinit (NOLOAD) :
{
. = ALIGN(4);
__noinit_start__ = .;
*(.noinit .noinit.*)
. = ALIGN(4) ;
__noinit_end__ = .;
} > DRAM
/* Check if there is enough space to allocate the main stack */
._stack (NOLOAD) :
{
. = ALIGN(4);
. = . + __Main_Stack_Size ;
. = ALIGN(4);
} >DRAM
这是输出的 ELF 文件:
arm-none-eabi-readelf.exe -l test.elf
Elf file type is EXEC (Executable file)
Entry point 0x601b9
There are 2 program headers, starting at offset 52
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
LOAD 0x010000 0x00060000 0x00060000 0x06840 0x06840 RWE 0x10000
LOAD 0x020000 0x20010000 0x20010000 0x00000 0x06084 RW 0x10000
Section to Segment mapping:
Segment Sections...
00 .text .ARM.exidx.reset .data
01 .systemclock .bss ._stack
为什么会有.bss 和._stack 部分?
谢谢!!
【问题讨论】:
-
你能澄清问题吗/你的问题,我最近在处理链接器脚本,但在这里看不到问题
-
NOLOAD关键字告诉加载器不应该加载给定的部分。我的期望是任何带有NOLOAD的部分都应该 NOT 出现在带有 LOAD 标志的 ELF 输出文件程序头中,但它们确实出现了。我想知道为什么。 -
您提到的另一个堆栈溢出问题引用了NOLOAD(输出节类型)的定义。此定义明确表示链接器将正常处理该部分,然后不会导致 ELF w.r.t 发生任何变化。本节(加载程序的添加属性除外)。加载器负责不加载这些部分。
-
好的,但接下来的问题是:加载程序应该如何知道不应该加载这些?当一个符号放在
.noinit部分时,链接器将它从.bss移动到.noload,我期待这里有类似的东西吗? -
也许您必须将该部分实际移动到专用的 segment 中,然后才不会加载? IIRC 节表在 ELF 可执行文件中是可选的...
标签: c gcc ld linker-scripts