使用以下CFLAGS
:
-Wall -Werror -Wextra -pedantic -std=c99 -O3 -nostartfiles -nodefaultlibs
我的__start
入口点(通知-nostartfiles
)已成功编译并放入输出可执行文件中。
然而,当我添加-flto
标志时,它所调用的入口点和函数都被优化掉了。此外,以下链接既不是错误也不是警告,而是使用不正确的(随机)入口点。
一个问题如何防止__start
功能被优化。它对我来说也很有趣,为什么链接器“忘记”缺少默认的我的入口点的外部依赖。
我的GCC版本是 gcc(i686-posix-dwarf-rev1,由MinGW-W64项目建造)4.9.2 。
UPD:
源代码(在@FUZxxl的帮助下修复,他在Windows ABI中写了关于前置下划线的内容):
#include <windows.h>
void _start()
{
MessageBox(NULL, TEXT("Hello world."), TEXT(""), MB_OK);
ExitProcess(0);
}
链接器(-S
)发出的程序集输出:
非-flto
版本:
Disassembly of section .text:
00401000 <__start>:
401000: 83 ec 1c sub $0x1c,%esp
401003: c7 44 24 0c 00 00 00 movl $0x0,0xc(%esp)
40100a: 00
40100b: c7 44 24 08 00 20 40 movl $0x402000,0x8(%esp)
401012: 00
401013: c7 44 24 04 0d 20 40 movl $0x40200d,0x4(%esp)
40101a: 00
40101b: c7 04 24 00 00 00 00 movl $0x0,(%esp)
401022: ff 15 54 40 40 00 call *0x404054
401028: 83 ec 10 sub $0x10,%esp
40102b: c7 04 24 00 00 00 00 movl $0x0,(%esp)
401032: ff 15 4c 40 40 00 call *0x40404c
401038: 90 nop
401039: 90 nop
40103a: 90 nop
40103b: 90 nop
40103c: 90 nop
40103d: 90 nop
40103e: 90 nop
40103f: 90 nop
00401040 <__CTOR_LIST__>:
401040: ff (bad)
401041: ff (bad)
401042: ff (bad)
401043: ff 00 incl (%eax)
401045: 00 00 add %al,(%eax)
...
00401048 <__DTOR_LIST__>:
401048: ff (bad)
401049: ff (bad)
40104a: ff (bad)
40104b: ff 00 incl (%eax)
40104d: 00 00 add %al,(%eax)
-flto
版本(注意此处缺少_start
,只是API条目的一堆thunk:)
Disassembly of section .text:
00401000 <_ExitProcess@4>:
401000: ff 25 4c 30 40 00 jmp *0x40304c
401006: 90 nop
401007: 90 nop
00401008 <_MessageBoxA@16>:
401008: ff 25 54 30 40 00 jmp *0x403054
40100e: 90 nop
40100f: 90 nop
00401010 <__CTOR_LIST__>:
401010: ff (bad)
401011: ff (bad)
401012: ff (bad)
401013: ff 00 incl (%eax)
401015: 00 00 add %al,(%eax)
...
00401018 <__DTOR_LIST__>:
401018: ff (bad)
401019: ff (bad)
40101a: ff (bad)
40101b: ff 00 incl (%eax)
40101d: 00 00 add %al,(%eax)
答案 0 :(得分:3)
使用您设置的所有异国情调/嵌入式相关选项,您必须确保您的符号被视为您的入口点而不是链接器优化所收集的垃圾(--gc-sections
也这样做:收集& #34;无用的&#34;部分)
由于无法访问任何部分,因此最终可以使用完全空.elf
个文件。
告诉链接器您正在使用该符号作为入口点(并避免链接器逃避它!),只需添加
-Wl,-e__start
选项(或编写一个链接器规范文件,您声明符号,但命令行选项更容易)