有没有办法防止添加的 .o 文件部分从 gnu 链接器垃圾收集中删除?

Is there a way to prevent an added .o file section of being removed from gnu linker garbage collection?

我有一个非对称双核 (ARM) 控制器(A5 内核和 M4 内核)。 我想创建一个二进制文件,我可以将其写入控制器的 RAM/ROM,然后为两个内核执行代码。 我将 M4 代码作为 .o 文件包含在 A5 链接器 ld 中。由于选项 --gc-sections,该部分已被垃圾回收。有什么方法可以保留此部分,但仍对所有其他部分使用选项 --gc-sections

更详细:

我构建了 m4 代码并从二进制输出创建了一个 .o 文件。

COMMAND arm-none-eabi-objcopy.exe -O binary --gap-fill 0xff m4_tester.elf m4_tester.bin
COMMAND arm-none-eabi-objcopy.exe -I binary -O elf32-littlearm -B arm m4_tester.bin m4_tester.o

我将此文件作为一个部分包含在 A5 项目链接器 .ld 文件中:

    SECTIONS
    {  
      .m4stuff : { 
        . = ALIGN(4);
        m4_tester.o
        KEEP(*(.m4stuff))
        . = ALIGN(4);
        } > m4code

    ...
    }

到目前为止一切正常,在地图文件中看起来像这样:

.m4stuff        0x3f4e0000      0xd68
                0x3f4e0000                . = ALIGN (0x4)
 m4_tester.o()
 .data          0x3f4e0000      0xd68 m4_tester.o
                0x3f4e0000                _binary_m4_tester_bin_start
                0x3f4e0d68                _binary_m4_tester_bin_end
 *(.m4stuff)
                0x3f4e0d68                . = ALIGN (0x4)

现在我也想使用链接器选项--gc-sections。根据其定义,m4stuff 部分现在已被垃圾收集:

.m4stuff        0x3f4e0000        0x0
                0x3f4e0000                . = ALIGN (0x4)
 m4_tester.o()
 *(.m4stuff)
                0x3f4e0000                . = ALIGN (0x4)

有什么方法可以保留此部分,但仍对所有其他部分使用选项 --gc-sections

原则上,您的命令文件中的 KEEP 命令应该执行此操作。

来自GNU ld manual

3.6.4.4 Input Section and Garbage Collection

When link-time garbage collection is in use (‘--gc-sections’), it is often useful to mark sections that should not be eliminated. This is accomplished by surrounding an input section’s wildcard entry with KEEP(), as in KEEP((.init)) or KEEP(SORT_BY_NAME()(.ctors)).

This SO answer 包含一个可能有用的 KEEP 使用示例。

在 Jeremy 正确地说 KEEP 命令应该执行我要求的操作之后,我检查了我是如何错误地使用 KEEP 的。

我意识到 m4_tester.o 中的数据实际上被标记为 .data 部分,这是由 arm-none-eabi-objcopy.exe 完成的。

通过使用 KEEP(*(.data)) 而不是 KEEP(*(.m4stuff)) 它起作用了:

    SECTIONS
    {  
      .m4stuff : { 
        . = ALIGN(4);
        m4_tester.o
        KEEP(*(.data))
        . = ALIGN(4);
        } > m4code

    ...
    }

我还发现我可以使用选项 --rename-sectionarm-none-eabi-objcopy.exe

重命名该部分

有了这个,我可以将部分重命名为更独特的名称:

COMMAND arm-none-eabi-objcopy.exe -I binary -O elf32-littlearm -B arm --rename-section .data=.m4data m4_tester.bin m4_tester.o

现在我可以在链接器文件中使用它了:

    SECTIONS
    {  
      .m4stuff : { 
        . = ALIGN(4);
        m4_tester.o
        KEEP(*(.m4data))
        . = ALIGN(4);
        } > m4code

    ...
    }

地图文件显示:

.m4stuff        0x3f4e0000     0x8000
                0x3f4e0000                . = ALIGN (0x4)
 m4_tester.o()
 .m4data        0x3f4e0000     0x8000 m4_tester.o
                0x3f4e0000                _binary_m4_tester_bin_start
                0x3f4e8000                _binary_m4_tester_bin_end
 *(.m4data)
                0x3f4e8000                . = ALIGN (0x4)