【问题标题】:How to avoid STT_GNU_IFUNC symbols in your binary?如何避免二进制文件中的 STT_GNU_IFUNC 符号?
【发布时间】:2012-01-12 20:58:59
【问题描述】:

我需要部署到 Red Hat 4.1.2 机器(具有 gcc 4.1.2)。我在 Ubuntu 11.10 上使用 GCC 4.6.1 进行开发。不幸的是,我的构建过程创建的一些二进制文件在 RedHat 机器上不可用。原因似乎是 ABI 更改,根据another Stackoverflow question,这是由于引入了 STT_GNU_IFUNC 符号。有没有办法防止导出任何此类符号,以便我的二进制文件可以使用旧的 ABI?我使用 nm 在我的二进制文件中查找任何“i”类型的符号,但没有找到。

我问这个是因为我构建的一些其他二进制文件以及一些 3rd 方库(tbb、boost)没有使用新的 ABI,因此在 RedHat 机器上运行良好。

希望这很清楚。提前致谢。

【问题讨论】:

    标签: linux gcc abi


    【解决方案1】:

    一般来说,UNIX 系统支持向后二进制兼容性(在旧机器上构建的二进制文件继续在新机器上运行),但不支持反向兼容。您不能期望构建在新系统上的二进制文件可以在旧系统上运行。 STT_GNU_IFUNC 只是您将遇到的许多问题中的第一个

    如果您需要在较新的机器上构建一个可以在较旧机器上运行的二进制文件,请参阅this 文档。

    曾经有“apgcc:用于制作可移植二进制文件的 GCC 包装器”使这变得容易(从上面引用过),但它似乎已经消失了 ;-(

    最简单的选择是在旧机器上构建(我曾经在 RedHat 6.2 上构建,生成的二进制文件到处运行)。您不必在物理机上实际运行 RH-6.2,只需在 VM 中启动即可。

    另一个相对简单的选择是构建 chroot,同样使用旧发行版(例如 RH-6.2)中的工具和库。

    【讨论】:

    • 谢谢,这正是我所担心的。问题是我的构建环境正在利用 python 和 gcc 的相对较新的特性。我得把它调低。
    • 您通常可以在旧机器上构建新的 Python 和 GCC,然后使用它们。 GCC 的版本对于生成的库的可移植性并不重要。只有 glibc 的版本可以。
    • @EmployedRussian 您将我的问题标记为与此问题重复(stackoverflow.com/questions/54532815/…),但事实并非如此。请删除 [重复] 标记或考虑适当的答案。
    • 我质疑使用 chroot 的基本原理。出于所有实际目的,链接到最新符号(如果我们将.symver 排除在讨论之外)发生在链接时(即当可执行文件被链接时)。这意味着您也可以给链接器一个旧的libc.so 并将其指向-rpath-link。虽然这会在您使用比可用符号更新的符号时引起问题,但我认为我们可以同意本练习的全部目的是将您自己限制为较旧的符号并动态链接到可用的同样旧的 版本 .
    【解决方案2】:

    因为APGCC 似乎不再可用(可能herehere 除外)。这些glibc headers 目前似乎是通过包含一个较旧的头文件从 C 代码生成可移植 Linux 二进制文件的最便捷方式。

    【讨论】:

    • 您是否验证过这适用于静态库?也就是说:静态库通常只包含他们想要引用的 bare 函数名。但是假设我有一个引用 memcpy 的静态库,并且在 我自己的 代码中(.c 文件,.S ...)我小心地告诉汇编程序我希望使用 @987654328 @(在 amd64 上),静态库中的目标文件是否也会引用 memcpy@2.2.5 还是会引用最新的 memcpy(即 memcpy@2.14)?
    【解决方案3】:

    交叉编译到较旧的 linux 可能非常困难,这只是您将遇到的众多问题之一。

    也就是说,ABI兼容性问题可以通过添加-Wl,-fno-jump-tables来解决。

    【讨论】:

      猜你喜欢
      • 2011-12-31
      • 1970-01-01
      • 2013-03-24
      • 2013-05-31
      • 1970-01-01
      • 2022-11-02
      • 2012-12-01
      • 1970-01-01
      相关资源
      最近更新 更多