【问题标题】:Get -fPIE linker errors on RedHat, but not Ubuntu在 RedHat 上获取 -fPIE 链接器错误,但不是 Ubuntu
【发布时间】:2021-05-19 14:33:01
【问题描述】:

我在 Ubuntu 20.04 上将 32 位应用程序转换为 64 位。能够在 RedHat(实际上是 Amazon Linux)系统上构建和运行它,但是当我尝试在 Ubuntu 上以 64 位模式编译它时,我从链接器收到此错误(在 32 位模式下工作正常):

/usr/bin/ld: /u/apps/lib/libiodbc.a(connect.o): relocation R_X86_64_32 against symbol `iodbcdm_global_lock' can not be used when making a PIE object; recompile with -fPIE

libiodbc.a 是我从 OpenLink 预编译的 odbc 驱动程序加载程序的一个版本(因为我找不到 32 位版本的包)。 Openlink 给了我 32 位和 64 位版本。没有重新编译它,但它可以在 RedHat 上运行 - 只是不是 Ubuntu。该库的 32 位版本在 Ubuntu 上可以正常链接。

RedHat 上是否有一些设置将所有编译默认为“与位置无关的可执行文件”模式,而在 Ubuntu (20.04) 上该设置不同?我想我可以回去并将 -fPIE 添加到我的全局编译器标志中(这会解决这个问题吗?),但我想知道为什么 Ubuntu 会抱怨而 RedHat 没有。

另外,我以前使用过 -fPIC 来处理共享库,但从未使用过 -fPIE。如果我用 -fPIE 构建所有东西,-fPIC 是多余的吗?

【问题讨论】:

    标签: ubuntu gcc redhat ld


    【解决方案1】:

    没关系(有点)。由于 Ubuntu 确实 在软件包 libiodbc2-dev 中提供了 64 位版本的 libiodbc.a,因此我安装了它,并且该版本链接正常。哦。在 RedHat 上,发行版的 64 位库已经安装,并且正在从那里获取 - 所以我猜 OpenLink 64 位版本从未在任何地方成功链接。

    我想我的问题仍然存在。是不是我从 OpenLink 获得的 64 位库是用 -fPIE 标志编译的,这使得它与我自己在本地编译的代码不兼容?我应该对所有事情都使用 -fPIE 吗?

    【讨论】:

      【解决方案2】:

      是的,我相信 RedHat 已将 GCC 配置为默认为 PIE,作为提高系统整体安全性的一种方式。使用 PIE 编译时,内核每次可以将程序加载到一个随机地址(Address Space Randomization,ASR),从而可以阻止依赖于特定地址空间布局的攻击。

      鉴于您有一个显然未使用 PIE 编译的预编译对象,您需要使用 -no-pie 链接(您也可以使用 -fno-pie 编译其余代码)。

      不,-fPIC-fPIE 没有冗余。在为共享库编译代码时,它必须是 PIC,这对生成的代码施加了比 PIE 更多的约束。您可以将-fPIC-fPIE 用于主程序代码并仍然构建与位置无关的可执行文件,但您必须将-fPIC 用于共享库代码。

      【讨论】:

      • 有趣。我认为 Ubuntu 也默认使用 PIE,因为我有时不得不使用 -no-pie 来让应用程序在存储指针和状态数据以在多个调用中使用时运行。但是,是的,该库的构建方式一定与我本地编译的对象的构建方式相反......
      猜你喜欢
      • 2019-07-15
      • 1970-01-01
      • 1970-01-01
      • 2011-02-23
      • 2014-08-12
      • 2023-04-01
      • 1970-01-01
      • 2017-01-23
      • 1970-01-01
      相关资源
      最近更新 更多