2016-09-18 46 views
3

用下面CFLAGS防止__start切入点被优化掉了

-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) :

  1. -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) 
    
  2. -flto版本(注意缺乏_start这里,只是一个为API条目一堆的thunk的):

    Disassembly of section .text: 
    
    00401000 <[email protected]>: 
        401000:  ff 25 4c 30 40 00  jmp *0x40304c 
        401006:  90      nop 
        401007:  90      nop 
    
    00401008 <[email protected]>: 
        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

来源,请。另外,C还是C++?他们不是同一种语言。 – xaxxon

+0

另外,你为什么要__start在那里? __start没有被发射出什么问题? –

+1

您是否尝试添加'-Wl,-e__start'来强制入口点? –

回答

3

与所有的异国/嵌入式与你设置的相关选项,你必须确保你的符号被视为你的入口点,而不是通过链接器优化收集垃圾(--gc-sections也这样做:收集“无用”部分)

由于没有任何部分可到达,因此您最终可能会得到完全空的.elf文件。

要告诉您正在使用该符号作为入口点链接(并避免了链接逃避吧!),只需添加

-Wl,-e__start

选项,您的链接命令(或写一个连接规范文件在哪里你声明你的符号,但命令行选项更容易)