防止__start入口点被优化

时间:2016-09-18 09:50:02

标签: c gcc optimization

使用以下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)发出的程序集输出:

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

1 个答案:

答案 0 :(得分:3)

使用您设置的所有异国情调/嵌入式相关选项,您必须确保您的符号被视为您的入口点而不是链接器优化所收集的垃圾(--gc-sections也这样做:收集& #34;无用的&#34;部分)

由于无法访问任何部分,因此最终可以使用完全空.elf个文件。

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

-Wl,-e__start

链接命令的

选项(或编写一个链接器规范文件,您声明符号,但命令行选项更容易)