https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91299
Bug ID: 91299 Summary: LTO inlines a weak definition in presence of a non-weak definition from an ELF file Product: gcc Version: 8.2.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: lto Assignee: unassigned at gcc dot gnu.org Reporter: peter.smith at linaro dot org CC: marxin at gcc dot gnu.org Target Milestone: --- The following example has been cut down from an embedded program that uses absolute symbols to denote entry points. I've used arm-none-eabi-gcc 8.2.1 in this example but it will reproduce on at least gcc 7.4.0 x86_64 with binutils 2.26.1 : cat nonweakdef.s .globl foo .equ foo, 0x10000000 cat weakdef.c __attribute__((weak)) void foo() {} int main(void) { foo(); return 0; } arm-none-eabi-gcc -O3 nonweakdef.s weakdef.c -mcpu=cortex-m3 -o foo.axf --specs=nosys.specs produces the disassembly output for main: 00008030 <main>: 8030: b508 push {r3, lr} 8032: f000 e9ae blx 8390 <__foo_veneer> 8036: 2000 movs r0, #0 8038: bd08 pop {r3, pc} 803a: bf00 nop This shows a function call to a __foo_veneer as I would expect as the definition of foo is far away from main. With LTO the weak definition of foo is inlined into main arm-none-eabi-gcc -O3 nonweakdef.s weakdef.c -flto -mcpu=cortex-m3 -o foo.axf --specs=nosys.specs 0000802c <main>: 802c: 2000 movs r0, #0 802e: 4770 bx lr This ignores the non-weak definition in the ELF file which should take precedence. In the embedded example this was fatal as the non-weak definition represented the entry point for a device specific flash programming routine overriding a platforms generic one. I think that either the linker ld.bfd 2.31.51.20181213 is not passing the non-weak definition information to the LTO plugin which should inhibit the inlining of the weak definition or some optimization is enabled for LTO that isn't accounting for a non-weak definition to be present from a non LTO source. As such this might be a bug in binutils rather than GCC.