https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116334
Bug ID: 116334
Summary: LTO dllimport generates ureferenced symbol and unused
code
Product: gcc
Version: 12.2.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: lto
Assignee: unassigned at gcc dot gnu.org
Reporter: pali at kernel dot org
Target Milestone: ---
When compiling single source application with calls external dllimport function
then LTO generates unreferenced symbol and unused dead code in the final
binary. When same source is compiled without LTO then there is no dead code in
binary.
Take following example:
__declspec(dllimport) extern int __stdcall MessageBoxA(void *, const char *,
const char *, unsigned int);
__attribute__((used))
int WinMainCRTStartup(void)
{
MessageBoxA((void *)0, "Message", "Title", 0);
return 0;
}
And compile it without LTO:
$ i686-w64-mingw32-gcc unreferenced.c -o unreferenced.exe -mwindows
-nostartfiles -nostdlib -luser32 -Wl,--disable-runtime-pseudo-reloc -W -Wall
-Os
Compiled binary under objdump looks like:
$ objdump -d unreferenced.exe
unreferenced.exe: file format pei-i386
Disassembly of section .text:
00401000 <_WinMainCRTStartup>:
401000: 55 push %ebp
401001: 31 c0 xor %eax,%eax
401003: 31 d2 xor %edx,%edx
401005: 89 e5 mov %esp,%ebp
401007: 83 ec 18 sub $0x18,%esp
40100a: 89 44 24 0c mov %eax,0xc(%esp)
40100e: c7 44 24 08 00 20 40 movl $0x402000,0x8(%esp)
401015: 00
401016: c7 44 24 04 06 20 40 movl $0x402006,0x4(%esp)
40101d: 00
40101e: 89 14 24 mov %edx,(%esp)
401021: ff 15 30 40 40 00 call *0x404030
401027: 31 c0 xor %eax,%eax
401029: 83 ec 10 sub $0x10,%esp
40102c: c9 leave
40102d: c3 ret
40102e: 90 nop
40102f: 90 nop
00401030 <__CTOR_LIST__>:
401030: ff (bad)
401031: ff (bad)
401032: ff (bad)
401033: ff 00 incl (%eax)
401035: 00 00 add %al,(%eax)
...
00401038 <__DTOR_LIST__>:
401038: ff (bad)
401039: ff (bad)
40103a: ff (bad)
40103b: ff 00 incl (%eax)
40103d: 00 00 add %al,(%eax)
...
Now compile it again but with enabled LTO with additional -flto switch. objdump
shows:
$ objdump -d unreferenced.exe
unreferenced.exe: file format pei-i386
Disassembly of section .text:
00401000 <_WinMainCRTStartup>:
401000: 55 push %ebp
401001: 31 c0 xor %eax,%eax
401003: 31 d2 xor %edx,%edx
401005: 89 e5 mov %esp,%ebp
401007: 83 ec 18 sub $0x18,%esp
40100a: 89 44 24 0c mov %eax,0xc(%esp)
40100e: c7 44 24 08 00 20 40 movl $0x402000,0x8(%esp)
401015: 00
401016: c7 44 24 04 06 20 40 movl $0x402006,0x4(%esp)
40101d: 00
40101e: 89 14 24 mov %edx,(%esp)
401021: ff 15 30 40 40 00 call *0x404030
401027: 31 c0 xor %eax,%eax
401029: 83 ec 10 sub $0x10,%esp
40102c: c9 leave
40102d: c3 ret
40102e: 90 nop
40102f: 90 nop
00401030 <_MessageBoxA@16>:
401030: ff 25 30 40 40 00 jmp *0x404030
401036: 90 nop
401037: 90 nop
00401038 <__CTOR_LIST__>:
401038: ff (bad)
401039: ff (bad)
40103a: ff (bad)
40103b: ff 00 incl (%eax)
40103d: 00 00 add %al,(%eax)
...
00401040 <__DTOR_LIST__>:
401040: ff (bad)
401041: ff (bad)
401042: ff (bad)
401043: ff 00 incl (%eax)
401045: 00 00 add %al,(%eax)
...
At address 0x401030 there is dead code (nothing references address 0x401030)
and also unreferenced symbol _MessageBoxA@16.