My target device is an EFM32 Cortex-M3 based device. My toolchain is the official ARM GNU toolchain gcc-arm-none-eabi-8-2018-q4-major.
Everything works fine without LTO, but to make LTO work I have to mark all interrupt handler code with -fno-lto
. I would like to get rid of this workaround.
The problem is, every interrupt handler is getting removed from the final binary. (I am checking with arm-none-eabi-nm --print-size --size-sort --radix=d -C -n file.out
) This makes the resulting binary crash.
Digging deeper and after googling for similar problems:
- I tried marking such functions as
__attribute__((used))
,__attribute((interrupt))
to no avail - the interrupt handlers are getting removed in spite of these attributes. (related Prevent GCC LTO from deleting function) - Found possibly related discussion https://bugs.launchpad.net/gcc-arm-embedded/+bug/1747966 - no solutions posted
Sample code from startup_efm32gg.c
defines default interrupt handlers as such:
void DMA_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler")));
/* many other interrupts */
void Default_Handler(void) { while (1); }
The same problem happens for regular interrupt handler definitions as well (as in, no aliases and not weak)
It might be related but it seems that weak symbols are misbehaving in LTO mode in the same way.
Thank you in advance for any ideas!
Edit: See my reply to the marked answer for a full solution!