在 --gc-sections 之后更新链接器变量

Update linker variables after --gc-sections

我在 cortex-a9 板上写了一个小的二进制文件,并定义了一个这样的链接描述文件:

SECTIONS
{
    .text :
    {
        __text = . ;
        *(.vector)
        *(.text)
        *(.text.*)
    }

    .rodata :
    {
        *(.rodata)
        *(.rodata.*)
    }

    .data   :  {
        __data_start = . ;
        *(.data)
        *(.data.*)
    }
    . = ALIGN(4);
    __bss_start = . ;
    .bss       :
    {
      *(.bss)
      *(.bss.*)
      *(COMMON)
    . = ALIGN(4);
    }
    __bss_end = .;

    . = ALIGN(4);
    __heap_start = .;
    . = . + 0x1000;    
    . = ALIGN(4);
    __heap_end = .;
     _end = .       ;
    PROVIDE (end = .)   ;
}

但似乎在 --gc-sections 工作并删除未使用的部分之后,__heap_start 仍然是 --gc-sections 工作之前的值(我在代码中打印它并检查 ld 标志):

arm-linux-gnueabihf-gcc -mcpu=cortex-a7 -msoft-float -nostdlib -Wl,--gc-sections -Wl,--print-gc-sections -Wl,-Ttext,0x04000000 -T csrvisor.lds -Wl,-Map,binary.map

有人知道如何在 --gc-sections 删除未使用的部分后将 __heap_start 更改为更正值吗?

  • 检查你的编译器标志:它们真的包含-ffunction-sections -fdata-sections吗?

  • 堆通常(在您的情况下也是如此)在 .bss 部分之后立即开始。因此,对于堆的开始,您的链接描述文件看起来不错

  • 检查链接器是否真的删除未使用的变量 - 如果它只删除未使用的文本部分,则值__heap_start不会变。

代码、只读数据、初始化数据等。阿尔。通常进入闪光灯。如果某些东西在那里被垃圾收集,它不会影响你的堆。

数据(已初始化和未初始化)将(最终)出现在 RAM 中。如果有东西在那里被垃圾收集,它会影响你的堆。所以检查你是否真的有被垃圾收集删除的变量。

至于你的链接描述文件

  • 没有KEEP声明。通常类似于重置处理程序,main 等。阿尔。不能被链接器垃圾收集删除

  • 您的数据部分没有定义初始值的处理。

  • 您的链接描述文件不包含区域声明 (MEMORY)。检查哪些默认值适用

  • 您的部分没有目标区域:再次检查哪些默认值适用于您的情况。

目标区域示例:

.rodata :
{
    *(.rodata)
    *(.rodata.*)
} >rom

.data   :  {
    __data_start = . ;
    *(.data)
    *(.data.*)
} >ram