c - 32位x86代码是否需要专门为共享库文件进行PIC编译?

标签 c linux shared-libraries elf pic

如果要将目标文件作为共享库 (.so) 加载,则将代码编译为目标文件需要与位置无关,因为共享库的基本虚拟地址文件在不同的进程中被载入可能会有所不同。

现在,当我尝试在 32 位 x86 计算机上加载未使用 -fpic GCC 选项编译和链接的 .so 文件时,我没有遇到错误,但它失败了在 64 位 x86 计算机上。

我发现的随机网站说我在 32 位上不需要 -fpic 因为没有 -fpic 编译的代码在使用时也根据 X86 32 位 ABI 巧合地工作以与位置无关的方式。但我仍然发现软件在其 32 位版本中附带不同版本的库:一种用于 PIC,一种用于非 PIC。例如,intel 编译器附带了 libirc.alibirc_pic.a,后者被编译为位置无关模式(如果想要链接那个 。 a 文件转换为 .so 文件)。

我想知道对于 32 位代码使用 -fpic 和不使用它之间的确切区别是什么,以及为什么一些软件包(例如 intel 编译器)仍然附带不同版本的库?

最佳答案

并非非 PIC 代码在 x86(32 位)上“巧合”地工作。这是 x86 的动态链接器支持使其工作所需的必要“textrels”。这会以非常高的内存消耗和启动时间为代价,因为基本上整个代码段都必须在加载时进行修补(因此成为不可共享的内存)。

动态链接器维护者声称由于架构中的基本问题(立即地址位移不能大于 32 位),x86_64 不支持非 PIC 共享库,但这个问题可以通过以下方式轻松解决总是在虚拟地址空间的前 4gb 中加载库。当然,PIC 代码在 x86_64 上非常便宜(PIC 不像在 32 位 x86 上那样是性能 killer )所以他们不支持它并防止傻瓜制作非 PIC 库可能是正确的...

关于c - 32位x86代码是否需要专门为共享库文件进行PIC编译?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6961832/

相关文章:

c - c1 如何在 va_arg 中获取这个值?

c++ - 比较两个 C 风格字符串的正确函数是什么?

linux - Jenkins : bash script ran with nohup is neither working nor writing anything to log

c++ - 运行时更新.so文件时如何传输STL容器数据

linux - 使用 dlopen() 加载共享库时出错

c - 带链表的多线程

c - 尝试使用 C 使 LED 闪烁

python - 使用脚本取消设置 PDF 字体

linux - 在带分隔符的文件中将一列复制到另一列

c - ./a.out : error while loading shared libraries: libgsl. so.23: 无法打开共享对象文件: 没有那个文件或目录