gcc - 为什么 fPIC 在 64 位平台上绝对必要,而不是在 32 位平台上?

标签 gcc shared-libraries 32bit-64bit dynamic-linking fpic

我最近收到了:

...relocation R_X86_64_32 against `a local symbol' can not be used when making a shared object; recompile with -fPIC

尝试将程序编译为共享库时出错。

现在解决这个问题并不是太困难(使用 -fPIC 重新编译所有依赖项),但经过一些研究发现这个问题仅存在于 x86-64 平台上。在 32 位上,任何位置相关代码仍然可以由动态加载器重定位。

最好的answer我能找到的是:

x86 has support for .text relocations (which is what happens when you have position-dependend code). This support comes at a cost, namely that every page containing such relocation becomes basically unshared, even if it sits in a shared library, thereby spoiling the very concept of shared libs. Hence we decided to disallow this on amd64 (plus it creates problems if the value needs more than 32bit, because all .text relocs only have size 'word32')

但我觉得这还不够。如果重定位破坏了共享库的概念,为什么它可以在 32 位平台上完成?另外,如果需要对 ELF 格式进行更改以支持 64 位,那么为什么不增加所有字段的大小以适应?

这可能是一个小问题,但它的动机是以下事实:a)有问题的代码是科学代码,最好不必受到性能影响,b)这些信息是不可能的首先找到!

[编辑:“答案”

@awoodlands answer可能是最好的“字面答案”,@servn added一些很好的信息。

在搜索有关不同类型搬迁的更多信息时,我发现了 this最终是x86_64 ABI reference (参见第 68 页) ]

最佳答案

据我了解,问题是 x86-64 似乎引入了一种新的、更快的相对于指令指针引用数据的方法,而 x86-32 不存在这种方法。

This article对此进行了深入的分析,并给出了以下执行摘要:

The ability of x86-64 to use instruction-pointer relative offsetting to data addresses is a nice optimisation, but in a shared-library situation assumptions about the relative location of data are invalid and can not be used. In this case, access to global data (i.e. anything that might be changed around on you) must go through a layer of abstraction, namely the global offset table.

-fPIC 寻址为寻址添加了一个额外的抽象层,以使以前在通常的寻址方式中可能实现的功能(也是一个理想的功能)仍然适用于较新的架构。

关于gcc - 为什么 fPIC 在 64 位平台上绝对必要,而不是在 32 位平台上?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7216244/

相关文章:

gcc - 如何告诉 Clang 停止伪装成其他编译器?

android - 如何为 Android 和 IOS 构建一个库?

macos - macosx-version-min 是什么意思?

c++ - 模板参数中的函数调用

c++ - 从 VS 到 GCC 的 C/C++ 宏扩展产生错误

angular - 访问另一个 Angular ​​度项目

linux - 共享库如何知道它所在的位置?

c++ - 如何在 C++ 中安全地比较 32 位整数与 64 位整数以及如何在内部比较有符号整数?

installation - 安装程序根据 CPU 架构(x86 32 位、x64 64 位等)选择 MSI

c - 链接 C 中的库,未识别的引用