【问题标题】:Why would gcc change the order of functions in a binary?为什么 gcc 会改变二进制中函数的顺序?
【发布时间】:2021-05-17 12:06:10
【问题描述】:
  • 关于强制二进制中的函数顺序以匹配源文件顺序的许多问题
  • 例如,this postthat post
  • 我不明白为什么 gcc 首先要改变他们的顺序
  • 可以从中获得什么?
  • 另外,为什么toplevel-reorder默认值为true?

【问题讨论】:

  • 为什么要关心二进制文件中函数的顺序?这应该在你的问题中解释
  • @BasileStarynkevitch 教育目的,更好地了解内部原理
  • 您应该联系法国的 Albert Cohen。给我发邮件,我知道他的。他的研究与你的非常接近。见this。艾伯特真的是一个非常好的人!

标签: c gcc ld


【解决方案1】:

GCC 可以更改函数的顺序,因为 C 标准(例如 n1570 或更新的)允许这样做。

GCC 没有义务将 C 函数编译为 ELF 格式意义上的单个函数。在 Linux 上查看 elf(5)

在实践中(启用优化:尝试使用gcc -Wall -fverbose-asm -O3 foo.c 编译foo.c,然后查看发出的foo.s 汇编程序文件),GCC 编译器正在构建像GIMPLE 这样的中间表示。大量优化正在将 GIMPLE 转变为更好的 GIMPLE。

一旦 GIMPLE 表示“足够好”,编译器会将其转换为 RTL

在 Linux 系统上,您可以使用 dladdr(3) 来查找离给定地址最近的 ELF 函数。您还可以使用backtrace(3) 在运行时检查您的call stack

GCC 甚至可以完全删除函数,尤其是调用将被内联扩展的 static 函数(即使 没有任何 inline 关键字)。

我倾向于相信,如果你编译和链接你的整个程序与 gcc -O3 -flto -fwhole-program 一些非静态但未使用的函数也可以删除......

您可以随时编写自己的GCC plugin 来更改函数的顺序。

如果你想猜测 GCC 是如何工作的:下载并研究它的源代码(因为它是免费软件)并在你的机器上编译它,invoke 它与 GCC developer options,在GCC mailing lists 上提问。 .

另请参阅bismon 静态源代码分析器(一些正在进行的工作可能会让您感兴趣)和DECODER 项目。您可以通过电子邮件与我联系。您还可以为RefPerSys 做出贡献并使用它来生成 GCC 插件(C++ 形式)。

【讨论】:

    【解决方案2】:

    从中可以得到什么?

    优化。如果编译器认为某些代码会被大量使用,它可能会将该代码放在与预期不会经常执行的代码不同的区域(或者是错误路径,其中性能不那么重要)。并且可能在其他代码之后或临时附近执行的代码应该放在附近,因此在需要时更有可能在缓存中。

    __attribute__((hot)) and __attribute__((cold)) 的存在出于某些相同的原因。

    为什么toplevel-reorder默认值为true?

    因为 99% 的开发人员都不会被这个默认设置所困扰,而且它可以让程序运行得更快。需要关心排序的 1% 的开发者使用属性、配置文件引导优化或其他可能与 no-toplevel-reorder 无论如何冲突的功能。

    【讨论】:

    • 只是为了确保我理解:二进制代码的重新排序与“打破”独立翻译的 C 函数的概念有关,并且与其他函数“正交”
    • @OrenIshShalom:我不明白你现在在问什么。
    • 不,它没有打破任何概念,因为没有任何概念。不应依赖内存中函数的顺序。
    • 抱歉,改写:如果来自foo 的一些“热”代码被移到它自己的部分,并且foo 出现在之前 bar 在源文件中,那么“hot-foo”部分可以在之后 bar
    • @OrenIshShalom:是的,因为默认情况下无法保证订购。
    猜你喜欢
    • 2015-11-07
    • 1970-01-01
    • 2017-08-18
    • 2018-06-13
    • 1970-01-01
    • 1970-01-01
    • 2022-10-01
    • 1970-01-01
    相关资源
    最近更新 更多