【问题标题】:Compiler output on different OS Versions不同操作系统版本上的编译器输出
【发布时间】:2018-05-27 14:22:19
【问题描述】:

据我了解(如果我错了,请纠正我),编译器的输出取决于所使用的体系结构版本、编译器和操作系统。

假设我使用 ubuntu 版本 16.04 x84-64 并使用 gcc 版本 5.4 编译 c 文件(或任何其他 OS、arch、编译器的组合,例如)。

据我了解,如果我要编译相同的 c 文件,但使用不同的 ubuntu 版本,使用相同的架构和编译器版本,它应该会生成相同的汇编代码。

经过几次尝试,我的印象是这是不正确的,这怎么可能?

编译器的输出是否取决于特定操作系统的版本?

其中一个示例是在 2 个不同的 ubuntu 版本上编译 https://github.com/tbuktu/libntru 并接收不同的程序集。

【问题讨论】:

  • 编译器输出还取决于优化标志(并且有 许多 个)。
  • 您如何确保在不同的操作系统版本上拥有相同的编译器版本?是否有可能它们的配置不同?例如one of them with --enable-default-pie,还是 -fstack-protector 的其他默认值?
  • 你是如何比较 asm 的?你是use gcc -O3 -S to get the compiler's actual asm output,还是反汇编了链接的二进制文件?或者您是否将二进制文件与cmp 或其他东西进行了比较?
  • @PeterCordes 地址空间布局随机化的一些人工制品是否可能会影响链接?不是随机化本身,因为这发生在加载时,而是根据一个操作系统支持的版本 X 和另一个操作系统支持的更高但兼容的版本 Y 对它的一些规定?
  • @Vroomfondel:也许吧。 --enable-default-pie 使 -pie-fpie 默认为可执行文件和库启用 ASLR。 (见我的第一条评论)。除此之外,我认为相同的 gcc 版本正在做相同的 asm。不同版本的 binutils 可能会以不同方式设置 ELF 标头中的某些位,但 OP 询问的是 asm 差异,而不是二进制差异。不同的做ASLR的方式还是只需要PIC代码,所以区别只是-fpie与否。

标签: gcc assembly compilation operating-system


【解决方案1】:

不同的操作系统可能安装了不同版本的默认库(链接到您的最终应用程序中)。因此最终结果可能会略有不同。

【讨论】:

  • 几乎所有东西都使用动态库,这些库没有链接。不同的是这些库的headers,可能包括不同的函数签名或不同的类型。通常链接的唯一额外内容是 gcc 附带的 CRT 启动代码 (/usr/lib/crt*.o)。无论如何,这不是编译器 asm 输出的一部分,而是链接器二进制输出的一部分。
【解决方案2】:

如果您只是在做几个 ubuntu 版本,那么差异的可能性就会降低,因为整体架构差异可能不会反映在您的测试中,或者可能不会在具有相同编译器系列的同一个操作系统系列上长时间改变.当您获得相同发行版的旧版本时,您更有可能在这样的测试中看到差异,新/最新版本的编译器不会直接作为 apt-get 移植/支持。也许您可以让他们通过手工构建来工作,但 gcc 尤其糟糕的是,他们的代码只能使用相对较新的先前或后续版本构建,并且相距太远而 gcc 无法构建 gcc。我首先期望看到的是完全由于 gcc 版本差异,您开始看到编译器中的差异。

更好的测试是获取一个简单的 .c 文件并为 windows 构建任何版本(使用为该系统构建的相同版本的 gcc)和 ubuntu/linux 任何版本。应该更快地看到差异。

两个不同的编译器应该针对合理规模的项目或基于知识的目标小代码示例(例如 llvm/clang 与 gcc)显示差异。同一个编译器或编译器系列的不同版本在定义上会随着时间的推移而有所不同,6.x 与 6.x+1 gcc 是否很好地显示差异是的,如果你知道在哪里看但通常不知道,但 gcc 3.x 与 gcc 7.x 应该然后根据您可以从那里缩小的测试范围。

您在相同的操作系统和系统上存在编译器与编译器之间的差异,预计会出现差异。

使用相同编译器的系统与系统之间的差异会显示出差异的原因有多种。

然后上面的组合自然也会显示出差异。

更大的问题是您为什么要关心,教育信息是,如果您更改编译器、编译器设置或操作系统,您不应该期望相同的 C 源代码以相同的方式构建。基于上述任何一项,它可以有从没有差异到巨大差异的任何地方。从优化和其他调整设置开始,然后从那里开始。

【讨论】:

  • 顺便说一句,stackoverflow 上已经多次询问和回答了这个问题
猜你喜欢
  • 2011-12-01
  • 2013-05-03
  • 1970-01-01
  • 2012-07-07
  • 2021-01-11
  • 1970-01-01
  • 1970-01-01
  • 2022-11-05
  • 1970-01-01
相关资源
最近更新 更多