I use a non-commercial license in Keil.
I have the following linker script
LOAD1 0x08000000 8192 { ROOT 0x08000000 8192 { *.o (RESET, +first) *(InRoot$$Sections) .any (+ro) } RAM1 0x20000000 UNINIT 16 { *(.bss.bootInfo) } RAM2 0x20000010 20464 { .any (+rw, +zi) } } LOAD2 0x0800FC00 1024 { ROM 0x0800FC00 UNINIT 1024 { *.o (.bss.nvmConfig) } }
I searched for the syntax for defining uninitialized sections of the linker script in the official source https://developer.arm.com/documentation/ka003046/latest.
The project contains several files, one of which defines a structure with manual placement in a section (boot.c)
static struct { char key[8]; u32 entryFlags; } volatile BootInfo __attribute__((section(".bss.bootInfo")));
Another file can_bootloader.c defines a structure with the same name and automatic placement
static struct { u32 isConnected : 1, isWBufFillingMode : 1, : 30; u32 wBufOffset; u8 wBuf[WBUF_SIZE]; u32 memoryOffset; } BootInfo;
On optimizations without LTO, the linker returns an error
Error: L6220E: Execution region RAM1 size (56 bytes) exceeds limit (16 bytes). Region contains 0 bytes of padding and 0 bytes of veneers (total 0 bytes of linker generated content).
Error: L6221E: Execution region RAM1 with Execution range [0x20000000,0x20000038) overlaps with Execution region RAM2 with Execution range [0x20000010,0x20001050).
In this case, the contents of the map file
BootInfo 0x20000000 Data 44 can_bootloader.o(.bss.BootInfo)
BootInfo 0x2000002c Data 12 boot.o(.bss.bootInfo)
It is clear that the linker has reordered the logical affiliation of the structures and tried to place BootInfo from can_bootloader.c in the section that I reserved for BootInfo from boot.c, which is incorrect. In this case, for some reason, the linker does not distort the names to correctly process independent files.