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.

Reply via email to