GNU ARM toolchain v12.2 Beta1: ld include doesn't seem to work?

Hi all…

I'm in the process of porting a firmware project to a newer version of the GNU ARM toolchain, previously this was written for v6 of the toolchain, which is quite dated.  I'm currently doing some testing with v12.2 beta 1 -- probably won't use this in production (I'll likely use 11.3r1), but since the newer release is there, I'll use that to do the initial porting to possibly shake out some bugs that v12 may bring.

One issue I'm hitting is with `ld`… I won't post the _actual_ code being used, but I'll instead post this simple little test case:

stuartl@vk4msl-ws:/tmp/test$ tail -n +0 *
==> boot.c <==
#include <stdbool.h>
int main(void) {
        while (true);
        return 0;
}

==> boot.ld <==
INCLUDE "mem.ld"

ENTRY(main)
SECTIONS
{
        .reserved_app : ALIGN(4)
        {
                . = 0x00000000;
                application_start = .;
                FILL(0xff);
                . += LENGTH(APPLICATION) - 1;
                BYTE(0xff);
        } > APPLICATION=0xffffffff

        .text : ALIGN(4)
        {
                _text = .;
                *(.text*)
                *(.rodata*)
                KEEP(*(.init))
                KEEP(*(.fini))
                /*
                 * Move vectors to top of flash to ensure 512-byte alignment.
                 * Failure to maintain alignment will result in a double
                 * hard-fault at boot.
                 */
                . = 0x006b40;
                *(.vectors)
                _etext = .;
        } > BOOTLOADER= 0

        .init_array :
        {
                _init_array = .;
                KEEP(*(SORT(.init_array.*)))
                KEEP(*(.init_array*))
                _einit_array = .;
        } > BOOTLOADER

        __exidx_start = .;
        .ARM.exidx : ALIGN(4)
        {
                *(.ARM.exidx* .gnu.linkonce.armexidx.*)
        } > BOOTLOADER
        __exidx_end = .;

        .data : ALIGN(4)
        {
                _data = .;
                *(.data*)
                _edata = .;
        } > SRAM AT > BOOTLOADER
        _ldata = LOADADDR(.data);

        .bss : ALIGN(4)
        {
                __bss_start__ = .;
                *(.bss*)
                *(COMMON)
                __bss_end__ = .;
        } > SRAM

        _heap = .;
        end = .;

        .stack : ALIGN(4)
        {
                _stack = .;
                *(.stack)
        } > STACK
}

==> Makefile <==
CROSS_COMPILE ?= arm-none-eabi-
CC = $(CROSS_COMPILE)gcc
CFLAGS = -fdata-sections -ffunction-sections -Os -g -mcpu=cortex-m3 -mfloat-abi=soft -mthumb
LDFLAGS = -T boot.ld -lc -lgcc -lnosys -Wl,-Map=boot.map

.PHONY: clean all

all: boot.elf

clean:
        rm -f boot.o boot.elf boot.map

boot.elf: boot.o
        $(CC) $(LDFLAGS) -o $@ $<

boot.o: boot.c

==> mem.ld <==
MEMORY
{
        APP_DATA (r) :          ORIGIN = 0x00200000,    LENGTH = 4096
        APPLICATION (rx) :      ORIGIN = 0x00201000,    LENGTH = 483328
        METADATA (r) :          ORIGIN = 0x00277000,    LENGTH = 8192
        BOOTLOADER (rx) :       ORIGIN = 0x00279000,    LENGTH = 32768
        SRAM (rwx) :            ORIGIN = 0x20000000,    LENGTH = 27K
        STACK (rwx) :           ORIGIN = 0x20006c00,    LENGTH = 5K
        PERIPHERAL (rw) :       ORIGIN = 0x40000000,    LENGTH = 0x20000000
        SYSPERIPH (rw) :        ORIGIN = 0xe0000000,    LENGTH = 0x00042000
}

The actual application has two parts that need to be built: one is a boot-loader, and the other is the main application.  To place the parts in the right spots, I use different linker scripts, but they have _common_ sections in their linker scripts, so these are split out into different files and included in the relevant linker script.

In older releases of the toolchain, this worked beautiful:

stuartl@vk4msl-ws:/tmp/test$ make clean all CROSS_COMPILE=/opt/gcc-arm-none-eabi-6-2017-q2-update/bin/arm-none-eabi-
rm -f boot.o boot.elf boot.map
/opt/gcc-arm-none-eabi-6-2017-q2-update/bin/arm-none-eabi-gcc -fdata-sections -ffunction-sections -Os -g -mcpu=cortex-m3 -mfloat-abi=soft -mthumb   -c -o boot.o boot.c
/opt/gcc-arm-none-eabi-6-2017-q2-update/bin/arm-none-eabi-gcc -T boot.ld -lc -lgcc -lnosys -Wl,-Map=boot.map -o boot.elf boot.o
stuartl@vk4msl-ws:/tmp/test$ cat boot.map 
Archive member included to satisfy reference by file (symbol)

/opt/gcc-arm-none-eabi-6-2017-q2-update/bin/../lib/gcc/arm-none-eabi/6.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-exit.o)
                              /opt/gcc-arm-none-eabi-6-2017-q2-update/bin/../lib/gcc/arm-none-eabi/6.3.1/../../../../arm-none-eabi/lib/crt0.o (exit)
/opt/gcc-arm-none-eabi-6-2017-q2-update/bin/../lib/gcc/arm-none-eabi/6.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-impure.o)
                              /opt/gcc-arm-none-eabi-6-2017-q2-update/bin/../lib/gcc/arm-none-eabi/6.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-exit.o) (_global_impure_ptr)
/opt/gcc-arm-none-eabi-6-2017-q2-update/bin/../lib/gcc/arm-none-eabi/6.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-init.o)
                              /opt/gcc-arm-none-eabi-6-2017-q2-update/bin/../lib/gcc/arm-none-eabi/6.3.1/../../../../arm-none-eabi/lib/crt0.o (__libc_init_array)
/opt/gcc-arm-none-eabi-6-2017-q2-update/bin/../lib/gcc/arm-none-eabi/6.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-memset.o)
                              /opt/gcc-arm-none-eabi-6-2017-q2-update/bin/../lib/gcc/arm-none-eabi/6.3.1/../../../../arm-none-eabi/lib/crt0.o (memset)
/opt/gcc-arm-none-eabi-6-2017-q2-update/bin/../lib/gcc/arm-none-eabi/6.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-__call_atexit.o)
                              /opt/gcc-arm-none-eabi-6-2017-q2-update/bin/../lib/gcc/arm-none-eabi/6.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-exit.o) (__call_exitprocs)
/opt/gcc-arm-none-eabi-6-2017-q2-update/bin/../lib/gcc/arm-none-eabi/6.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-atexit.o)
                              /opt/gcc-arm-none-eabi-6-2017-q2-update/bin/../lib/gcc/arm-none-eabi/6.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-__call_atexit.o) (atexit)
/opt/gcc-arm-none-eabi-6-2017-q2-update/bin/../lib/gcc/arm-none-eabi/6.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-fini.o)
                              /opt/gcc-arm-none-eabi-6-2017-q2-update/bin/../lib/gcc/arm-none-eabi/6.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-__call_atexit.o) (__libc_fini_array)
/opt/gcc-arm-none-eabi-6-2017-q2-update/bin/../lib/gcc/arm-none-eabi/6.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-lock.o)
                              /opt/gcc-arm-none-eabi-6-2017-q2-update/bin/../lib/gcc/arm-none-eabi/6.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-__call_atexit.o) (__retarget_lock_acquire_recursive)
/opt/gcc-arm-none-eabi-6-2017-q2-update/bin/../lib/gcc/arm-none-eabi/6.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-__atexit.o)
                              /opt/gcc-arm-none-eabi-6-2017-q2-update/bin/../lib/gcc/arm-none-eabi/6.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-atexit.o) (__register_exitproc)
/opt/gcc-arm-none-eabi-6-2017-q2-update/bin/../lib/gcc/arm-none-eabi/6.3.1/../../../../arm-none-eabi/lib/libnosys.a(_exit.o)
                              /opt/gcc-arm-none-eabi-6-2017-q2-update/bin/../lib/gcc/arm-none-eabi/6.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-exit.o) (_exit)

Allocating common symbols
Common symbol       size              file

__lock___atexit_recursive_mutex
                    0x1               /opt/gcc-arm-none-eabi-6-2017-q2-update/bin/../lib/gcc/arm-none-eabi/6.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-lock.o)
__lock___arc4random_mutex
                    0x1               /opt/gcc-arm-none-eabi-6-2017-q2-update/bin/../lib/gcc/arm-none-eabi/6.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-lock.o)
__lock___env_recursive_mutex
                    0x1               /opt/gcc-arm-none-eabi-6-2017-q2-update/bin/../lib/gcc/arm-none-eabi/6.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-lock.o)
__lock___sinit_recursive_mutex
                    0x1               /opt/gcc-arm-none-eabi-6-2017-q2-update/bin/../lib/gcc/arm-none-eabi/6.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-lock.o)
__lock___malloc_recursive_mutex
                    0x1               /opt/gcc-arm-none-eabi-6-2017-q2-update/bin/../lib/gcc/arm-none-eabi/6.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-lock.o)
__lock___at_quick_exit_mutex
                    0x1               /opt/gcc-arm-none-eabi-6-2017-q2-update/bin/../lib/gcc/arm-none-eabi/6.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-lock.o)
__lock___dd_hash_mutex
                    0x1               /opt/gcc-arm-none-eabi-6-2017-q2-update/bin/../lib/gcc/arm-none-eabi/6.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-lock.o)
__lock___tz_mutex   0x1               /opt/gcc-arm-none-eabi-6-2017-q2-update/bin/../lib/gcc/arm-none-eabi/6.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-lock.o)
__lock___sfp_recursive_mutex
                    0x1               /opt/gcc-arm-none-eabi-6-2017-q2-update/bin/../lib/gcc/arm-none-eabi/6.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-lock.o)

Memory Configuration

Name             Origin             Length             Attributes
APP_DATA         0x0000000000200000 0x0000000000001000 r
APPLICATION      0x0000000000201000 0x0000000000076000 xr
METADATA         0x0000000000277000 0x0000000000002000 r
BOOTLOADER       0x0000000000279000 0x0000000000008000 xr
SRAM             0x0000000020000000 0x0000000000006c00 xrw
STACK            0x0000000020006c00 0x0000000000001400 xrw
PERIPHERAL       0x0000000040000000 0x0000000020000000 rw
SYSPERIPH        0x00000000e0000000 0x0000000000042000 rw
*default*        0x0000000000000000 0xffffffffffffffff
… etc …

Even the standard Ubuntu 22.04 arm-none-eabi toolchain works:

stuartl@vk4msl-ws:/tmp/test$ make clean all
rm -f boot.o boot.elf boot.map
arm-none-eabi-gcc -fdata-sections -ffunction-sections -Os -g -mcpu=cortex-m3 -mfloat-abi=soft -mthumb   -c -o boot.o boot.c
arm-none-eabi-gcc -T boot.ld -lc -lgcc -lnosys -Wl,-Map=boot.map -o boot.elf boot.o
stuartl@vk4msl-ws:/tmp/test$ arm-none-eabi-gcc --version
arm-none-eabi-gcc (GNU Arm Embedded Toolchain 9-2020-q2-update) 9.3.1 20200408 (release)
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

stuartl@vk4msl-ws:/tmp/test$ cat boot.map 
Archive member included to satisfy reference by file (symbol)

/opt/gcc-arm-none-eabi-9-2020-q2-update/bin/../lib/gcc/arm-none-eabi/9.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-exit.o)
                              /opt/gcc-arm-none-eabi-9-2020-q2-update/bin/../lib/gcc/arm-none-eabi/9.3.1/../../../../arm-none-eabi/lib/crt0.o (exit)
/opt/gcc-arm-none-eabi-9-2020-q2-update/bin/../lib/gcc/arm-none-eabi/9.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-impure.o)
                              /opt/gcc-arm-none-eabi-9-2020-q2-update/bin/../lib/gcc/arm-none-eabi/9.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-exit.o) (_global_impure_ptr)
/opt/gcc-arm-none-eabi-9-2020-q2-update/bin/../lib/gcc/arm-none-eabi/9.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-init.o)
                              /opt/gcc-arm-none-eabi-9-2020-q2-update/bin/../lib/gcc/arm-none-eabi/9.3.1/../../../../arm-none-eabi/lib/crt0.o (__libc_init_array)
/opt/gcc-arm-none-eabi-9-2020-q2-update/bin/../lib/gcc/arm-none-eabi/9.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-memset.o)
                              /opt/gcc-arm-none-eabi-9-2020-q2-update/bin/../lib/gcc/arm-none-eabi/9.3.1/../../../../arm-none-eabi/lib/crt0.o (memset)
/opt/gcc-arm-none-eabi-9-2020-q2-update/bin/../lib/gcc/arm-none-eabi/9.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-__call_atexit.o)
                              /opt/gcc-arm-none-eabi-9-2020-q2-update/bin/../lib/gcc/arm-none-eabi/9.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-exit.o) (__call_exitprocs)
/opt/gcc-arm-none-eabi-9-2020-q2-update/bin/../lib/gcc/arm-none-eabi/9.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-atexit.o)
                              /opt/gcc-arm-none-eabi-9-2020-q2-update/bin/../lib/gcc/arm-none-eabi/9.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-__call_atexit.o) (atexit)
/opt/gcc-arm-none-eabi-9-2020-q2-update/bin/../lib/gcc/arm-none-eabi/9.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-fini.o)
                              /opt/gcc-arm-none-eabi-9-2020-q2-update/bin/../lib/gcc/arm-none-eabi/9.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-__call_atexit.o) (__libc_fini_array)
/opt/gcc-arm-none-eabi-9-2020-q2-update/bin/../lib/gcc/arm-none-eabi/9.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-lock.o)
                              /opt/gcc-arm-none-eabi-9-2020-q2-update/bin/../lib/gcc/arm-none-eabi/9.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-__call_atexit.o) (__retarget_lock_acquire_recursive)
/opt/gcc-arm-none-eabi-9-2020-q2-update/bin/../lib/gcc/arm-none-eabi/9.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-__atexit.o)
                              /opt/gcc-arm-none-eabi-9-2020-q2-update/bin/../lib/gcc/arm-none-eabi/9.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-atexit.o) (__register_exitproc)
/opt/gcc-arm-none-eabi-9-2020-q2-update/bin/../lib/gcc/arm-none-eabi/9.3.1/../../../../arm-none-eabi/lib/libnosys.a(_exit.o)
                              /opt/gcc-arm-none-eabi-9-2020-q2-update/bin/../lib/gcc/arm-none-eabi/9.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-exit.o) (_exit)

Allocating common symbols
Common symbol       size              file

__lock___atexit_recursive_mutex
                    0x1               /opt/gcc-arm-none-eabi-9-2020-q2-update/bin/../lib/gcc/arm-none-eabi/9.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-lock.o)
__lock___arc4random_mutex
                    0x1               /opt/gcc-arm-none-eabi-9-2020-q2-update/bin/../lib/gcc/arm-none-eabi/9.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-lock.o)
__lock___env_recursive_mutex
                    0x1               /opt/gcc-arm-none-eabi-9-2020-q2-update/bin/../lib/gcc/arm-none-eabi/9.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-lock.o)
__lock___sinit_recursive_mutex
                    0x1               /opt/gcc-arm-none-eabi-9-2020-q2-update/bin/../lib/gcc/arm-none-eabi/9.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-lock.o)
__lock___malloc_recursive_mutex
                    0x1               /opt/gcc-arm-none-eabi-9-2020-q2-update/bin/../lib/gcc/arm-none-eabi/9.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-lock.o)
__lock___at_quick_exit_mutex
                    0x1               /opt/gcc-arm-none-eabi-9-2020-q2-update/bin/../lib/gcc/arm-none-eabi/9.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-lock.o)
__lock___dd_hash_mutex
                    0x1               /opt/gcc-arm-none-eabi-9-2020-q2-update/bin/../lib/gcc/arm-none-eabi/9.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-lock.o)
__lock___tz_mutex   0x1               /opt/gcc-arm-none-eabi-9-2020-q2-update/bin/../lib/gcc/arm-none-eabi/9.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-lock.o)
__lock___sfp_recursive_mutex
                    0x1               /opt/gcc-arm-none-eabi-9-2020-q2-update/bin/../lib/gcc/arm-none-eabi/9.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-lock.o)

Memory Configuration

Name             Origin             Length             Attributes
APP_DATA         0x0000000000200000 0x0000000000001000 r
APPLICATION      0x0000000000201000 0x0000000000076000 xr
METADATA         0x0000000000277000 0x0000000000002000 r
BOOTLOADER       0x0000000000279000 0x0000000000008000 xr
SRAM             0x0000000020000000 0x0000000000006c00 xrw
STACK            0x0000000020006c00 0x0000000000001400 xrw
PERIPHERAL       0x0000000040000000 0x0000000020000000 rw
SYSPERIPH        0x00000000e0000000 0x0000000000042000 rw
*default*        0x0000000000000000 0xffffffffffffffff

BUT… ARM's latest (beta) toolchain does not like this:

stuartl@vk4msl-ws:/tmp/test$ make clean all CROSS_COMPILE=/tmp/arm-gnu-toolchain-12.2.mpacbti-bet1-x86_64-arm-none-eabi/bin/arm-none-eabi-
rm -f boot.o boot.elf boot.map
/tmp/arm-gnu-toolchain-12.2.mpacbti-bet1-x86_64-arm-none-eabi/bin/arm-none-eabi-gcc -fdata-sections -ffunction-sections -Os -g -mcpu=cortex-m3 -mfloat-abi=soft -mthumb   -c -o boot.o boot.c
/tmp/arm-gnu-toolchain-12.2.mpacbti-bet1-x86_64-arm-none-eabi/bin/arm-none-eabi-gcc -T boot.ld -lc -lgcc -lnosys -Wl,-Map=boot.map -o boot.elf boot.o
/tmp/arm-gnu-toolchain-12.2.mpacbti-bet1-x86_64-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/12.2.0/../../../../arm-none-eabi/bin/ld:boot.ld:15: warning: memory region `APPLICATION=0xffffffff' not declared
/tmp/arm-gnu-toolchain-12.2.mpacbti-bet1-x86_64-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/12.2.0/../../../../arm-none-eabi/bin/ld:boot.ld:30: warning: memory region `BOOTLOADER=' not declared
/tmp/arm-gnu-toolchain-12.2.mpacbti-bet1-x86_64-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/12.2.0/../../../../arm-none-eabi/bin/ld:boot.ld:30: syntax error
collect2: error: ld returned 1 exit status
make: *** [Makefile:14: boot.elf] Error 1

Is there something I've missed?