链接器命令语言 LD 的条件语句

conditional statements for linker command language LD

GNU LD 链接器命令语言是否有条件语句?

上下文:我正在为 arm cortex m0+ 开发固件,它由引导加载程序和应用程序组成。两者都在不同的项目中编译和刷新到目标,但我使用了一个框架,它带有指向驱动程序、makefile 和加载程序脚本的符号链接,这样我就可以为我制作的每个应用程序重复使用这些文件,而无需为每个应用程序复制这些文件。 目前我有两个loader文件,bootloader和application(makefile自动指定合适的),内存分配如下:

引导程序

MEMORY { 
  flash (rx)  : ORIGIN = 0x00000000, LENGTH = 16K
  ram   (rwx) : ORIGIN = 0x1FFFF000, LENGTH =  16K
}

应用程序

MEMORY { 
  flash (rx)  : ORIGIN = 0x00004000, LENGTH = 112K
  ram   (rwx) : ORIGIN = 0x1FFFF000, LENGTH =  16K
}

像makefile一样,我想把它们合并成这样(用C表达式来说明)

MEMORY { 
#ifdef(bootloaderSymbol)
  flash (rx)  : ORIGIN = 0x00000000, LENGTH = 16K
#else
  flash (rx)  : ORIGIN = 0x00004000, LENGTH = 112K
#endif
  ram   (rwx) : ORIGIN = 0x1FFFF000, LENGTH =  16K
}

虽然这不是它的主要目的,但您始终可以 运行 C 预处理器 (cpp) 在您的链接描述文件中:

#if defined(MACHINE1)
#    define TARGET_ADDRESS 0x80000000
#    define SDRAM_START xxx
#    define SDRAM_SIZE yyy
#    define ROMFLAGS   rx
#elif defined(MACHINE2)
#    define TARGET_ADDRESS 0x40000000
#    define SDRAM_START zzz
#    define SDRAM_SIZE  aaa
#    define ROMFLAGS rwx
#else
#    error unknown machine
#endif

MEMORY
{
   rom (ROMFLAGS) : ORIGIN = TARGET_ADDRESS, LENGTH = 0x00100000
   ram (WX) : ORIGIN = SDRAM_START + SDRAM_SIZE - 0x00200000, LENGTH = 0x00100000
   driver_ram (WX) : ORIGIN = SDRAM_START + SDRAM_SIZE - 0x00100000, LENGTH = 0x00100000
}

...

您只需要确保您的宏不会与链接描述文件语法冲突。然后将您的链接器脚本保存为 xxx.lk.in(而不是 xxx.lk)并向您的 Makefile 添加一个配方:

xxx.lk: xxx.lk.in
        $(CPP) -P $(INCLUDE) -D$(MACHINE) $< $@

剩下要做的就是将 xxx.lk 添加为最终可执行文件构建配方的依赖项。我在我的许多项目中都成功地使用了类似的流程。

我以前也走过同样的路,后来发现有一个 ld 命令行参数来指定段原点,这减少了在链接描述文件中弄清楚它的需要。来自手册页:

   -Tbss=org
   -Tdata=org
   -Ttext=org
       Same as --section-start, with ".bss", ".data" or ".text" as the section name.

因此,在您的情况下,您将拥有 -Ttext=0(引导加载程序)或 -Ttext=0x00004000(应用程序)

我觉得你可以根据https://sourceware.org/binutils/docs/ld/Builtin-Functions.html

试试"DEFINED(symbol)"

此外,请不要忘记将“--defsym=bootloaderSymbol=1”传递给 ld。

MEMORY {
    flash (rx)  : ORIGIN = DEFINED(bootloaderSymbol) ? 0x00000000 : 0x00004000, LENGTH = DEFINED(bootloaderSymbol) ? 112K : 16K
    ram   (rwx) : ORIGIN = 0x1FFFF000, LENGTH =  16K
}