I’ve been hunting some LTO issues in our code and this is some of the weirdness. Its not about platformio specifically but maybe someone has some good ideas.
The main issue I have been looking at is that a weak definition of a function gets used instead of the strong one when i enable LTO.
I was trying to reduce an example of this when I ran into this that might be related. When I enable LTO in this example I can compile 2 strong definitions without issue. Without LTO GCC correctly gives an error.
Somewhat small reproduction:
platformio.ini:
[env:default]
platform = ststm32
board = hy_tinystm103tb
build_flags =
-Wl,-Map,"$BUILD_DIR/${PROGNAME}.map"
; what?: using -flto allows multiple strong definitions
-flto
src/main.c
int main(int argc, char* argv[]) {
(void)argc;
(void)argv;
while (1);
}
__attribute__ ((used)) void NMI_Handler(void){}
// what?: removing used makes flto error correctly
// void NMI_Handler(void){}
void _exit(int code) { (void)code; while (1);}
src/strong.c
void NMI_Handler(void){}
src/startup.S
.global g_pfnVectors
Default_Handler:
Infinite_Loop:
b Infinite_Loop
.size Default_Handler, .-Default_Handler
g_pfnVectors:
.word NMI_Handler
.weak NMI_Handler
.thumb_set NMI_Handler,Default_Handler
Some links that might be related:
謝憲譁 - Linker doesn’t replace weak functions in assembly with global function i (gnu.org)
Linker doesn’t replace weak functions in assembly with global function in C when LTO is turned on · Issue #172 · riscvarchive/riscv-gcc (github.com)