2026-07-18
The asker has a Cortex-M firmware image they build themselves, and they want to compile a separate standalone function that calls into the already-flashed functions by their existing absolute addresses. The new function will be flashed into its own page. Nothing gets relinked; the old ELF's symbols must be treated as fixed pins the new object binds against.
What makes this interesting is that it turns the linker inside out. Normally the linker resolves symbols by placing sections and computing addresses. Here, half the symbols already have addresses baked into ROM and cannot move. You need to tell the linker "trust me, foo lives at 0x0800_1234, don't allocate anything for it."
arm-none-eabi-nm --defined-only main.elf (or objdump -t) to get every symbol you may call.PROVIDE(foo = 0x08001235);
PROVIDE(bar = 0x08002101);
Note the Thumb LSB is set to 1. Cortex-M is Thumb-only, and the LSB tells BX/BLX to stay in Thumb state. If nm reports an even address, add 1 before feeding it to the linker.-mlong-calls so the compiler emits movw/movt + blx instead of a 24-bit relative bl — otherwise you can't reach across flash from your patch page.PATCH (rx) : ORIGIN = 0x08010000, LENGTH = 2K, and a SECTIONS block placing .text there.objcopy -O binary patch.elf patch.bin so your loader can program exactly the bytes for that page.__aeabi_* or memcpy. Those symbols must exist in the base ELF and be pinned via PROVIDE, or your patch will fail to link (or worse, link against a fresh copy that recurses into itself).-ffunction-sections --gc-sections; a function you want to call may have been discarded. Verify presence in the final ELF, not the object files..data/.bss without a coordinated RAM plan.