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.