https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118063
Bug ID: 118063 Summary: Building files with lto creates object files with an incomplete symbol table Product: gcc Version: 13.2.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: benediktibk at gmail dot com Target Milestone: --- Created attachment 59877 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=59877&action=edit example project The original start for this bug hunt was this issue in zephyr: https://github.com/zephyrproject-rtos/zephyr/issues/81674 There is also a PR which adds a sample which triggers the issue: https://github.com/zephyrproject-rtos/zephyr/pull/81679 The problem is that the linker (bfd) is unable to find memset, which is actually defined in the last file passed to the linker. This file is an archive, containing memset.c.obj which defines memset. As a workaround it is possible to add memset.c.obj additionally to the link command at the end. This fixes the undefined reference to memset, although the same object file is also contained in the archive. The problem only occurs if memset.c is compiled with lto. When memset.c is built with lto arm-none-eabi-nm is able to find memset as a defined symbol, but arm-none-eabi-objdump does not list memset in the symbol table. When memset.c is built without lto arm-none-eabi-nm and arm-none-eabi-objdump are both able to find memset. This exact problem is reproducible with this code: /* blub.c */ void * blub (void *m) { return m; } arm-none-eabi-gcc -mcpu=cortex-m7 -mtune=cortex-m7 -fcf-protection=none -ffunction-sections -o build/blub_lto.c.obj -c blub.c -flto=auto arm-none-eabi-nm build/blub_lto.c.obj 00000000 T blub arm-none-eabi-objdump --all-headers build/blub_lto.c.obj ... SYMBOL TABLE: 00000000 l df *ABS* 00000000 blub.c 00000000 l d .text 00000000 .text 00000000 l d .data 00000000 .data 00000000 l d .bss 00000000 .bss 00000000 l d .gnu.lto_.inline.e9823cc996ebd34e 00000000 .gnu.lto_.inline.e9823cc996ebd34e 00000000 l d .gnu.lto_.jmpfuncs.e9823cc996ebd34e 00000000 .gnu.lto_.jmpfuncs.e9823cc996ebd34e 00000000 l d .gnu.lto_.ipa_modref.e9823cc996ebd34e 00000000 .gnu.lto_.ipa_modref.e9823cc996ebd34e 00000000 l d .gnu.lto_.lto.e9823cc996ebd34e 00000000 .gnu.lto_.lto.e9823cc996ebd34e 00000000 l d .gnu.lto_blub.0.e9823cc996ebd34e 00000000 .gnu.lto_blub.0.e9823cc996ebd34e 00000000 l d .gnu.lto_.symbol_nodes.e9823cc996ebd34e 00000000 .gnu.lto_.symbol_nodes.e9823cc996ebd34e 00000000 l d .gnu.lto_.refs.e9823cc996ebd34e 00000000 .gnu.lto_.refs.e9823cc996ebd34e 00000000 l d .gnu.lto_.decls.e9823cc996ebd34e 00000000 .gnu.lto_.decls.e9823cc996ebd34e 00000000 l d .gnu.lto_.symtab.e9823cc996ebd34e 00000000 .gnu.lto_.symtab.e9823cc996ebd34e 00000000 l d .gnu.lto_.ext_symtab.e9823cc996ebd34e 00000000 .gnu.lto_.ext_symtab.e9823cc996ebd34e 00000000 l d .gnu.lto_.opts 00000000 .gnu.lto_.opts 00000000 l d .comment 00000000 .comment 00000000 l d .ARM.attributes 00000000 .ARM.attributes 00000001 O *COM* 00000001 __gnu_lto_slim When built without lto: arm-none-eabi-objdump --all-headers build/blub_nolto.c.obj ... SYMBOL TABLE: 00000000 l df *ABS* 00000000 blub.c 00000000 l d .text 00000000 .text 00000000 l d .data 00000000 .data 00000000 l d .bss 00000000 .bss 00000000 l d .text.blub 00000000 .text.blub 00000000 l d .comment 00000000 .comment 00000000 l d .ARM.attributes 00000000 .ARM.attributes 00000000 g F .text.blub 00000014 blub I assume this difference in the behaviour with objdump also causes the issue in zephyr.