【发布时间】:2016-09-18 09:50:01
【问题描述】:
以下CFLAGS:
-Wall -Werror -Wextra -pedantic -std=c99 -O3 -nostartfiles -nodefaultlibs
我的__start 入口点(通知-nostartfiles)已成功编译并放入输出可执行文件中。
但是,当我添加-flto 标志时,入口点和它调用的函数都被优化了。此外,执行以下链接时既没有错误也没有警告,但入口点不正确(随机)。
一个问题是如何防止__start函数被优化掉。我也很有趣,为什么链接器“忘记”了对 my 入口点的外部依赖,因为缺少默认入口点。
我的 GCC 版本是 gcc (i686-posix-dwarf-rev1, Built by MinGW-W64 project) 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)
【问题讨论】:
-
来源,请。另外,C 还是 C++?它们不是同一种语言。
-
另外,你为什么要 __start 在那里? __start 没有发出是什么问题?
-
您是否尝试过添加
-Wl,-e__start来强制入口点? -
@Jean-FrançoisFabre 不应该做任何事情,LTO 发生在编译器中。
-
@Arhad 您是否尝试将入口点命名为
_start而不是__start?在 Windows ABI 中,编译器会在 C 函数名称前隐式添加下划线,所以如果你的函数调用__start,则符号实际上是___start,这是错误的。
标签: c gcc optimization