【问题标题】:Prevent __start entry point from being optimized out防止 __start 入口点被优化掉
【发布时间】: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):

  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)
    

【问题讨论】:

  • 来源,请。另外,C 还是 C++?它们不是同一种语言。
  • 另外,你为什么要 __start 在那里? __start 没有发出是什么问题?
  • 您是否尝试过添加-Wl,-e__start 来强制入口点?
  • @Jean-FrançoisFabre 不应该做任何事情,LTO 发生在编译器中。
  • @Arhad 您是否尝试将入口点命名为 _start 而不是 __start?在 Windows ABI 中,编译器会在 C 函数名称前隐式添加下划线,所以如果你的函数调用 __start,则符号实际上是 ___start,这是错误的。

标签: c gcc optimization


【解决方案1】:

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

您最终可能会得到一个完全空的 .elf 文件,因为没有可访问的部分。

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

-Wl,-e__start

链接命令的选项(或在声明符号的地方编写链接器规范文件,但命令行选项更容易)

【讨论】:

    猜你喜欢
    • 2017-08-10
    • 2023-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-12
    相关资源
    最近更新 更多