位置无关代码的差异:x86 与 x86-64
我最近正在构建一个针对 x86-64 架构的特定共享库 (ELF),如下所示:
g++ -o binary.so -shared --no-undefined ... -lfoo -lbar
失败并出现以下错误:
创建共享库时,不能使用针对“本地符号”的重定位 R_X86_64_32;使用-fPIC重新编译
当然,这意味着我需要将其重建为与位置无关的代码,因此它适合链接到共享库。
但这在具有完全相同的构建参数的 x86 上运行得非常好。所以问题是,x86 上的重定位与 x86-64 上的重定位有何不同?为什么我不需要在前者上使用 -fPIC
进行编译?
I was recently building a certain shared library (ELF) targeting x86-64 architecture, like this:
g++ -o binary.so -shared --no-undefined ... -lfoo -lbar
This failed with the following error:
relocation R_X86_64_32 against `a local symbol' can not be used when making a shared object; recompile with -fPIC
Of course, it means I need to rebuild it as position-independent code, so it's suitable for linking into a shared library.
But this works perfectly well on x86 with exactly the same build arguments. So the question is, how is relocation on x86 different from x86-64 and why don't I need to compile with -fPIC
on the former?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我找到了一个很好且详细的解释,归结为:
I have found a nice and detailed explanation, which boils down to:
这是一个代码模型的问题。默认情况下,构建静态代码时假设整个程序将保留在内存地址空间的较低 2G 部分。共享库的代码需要针对另一个内存模型(PIC)进行编译,或者使用 -mcmodel=large 进行编译,而无需进行该假设。
请注意,-mcmodel=large 在较旧的 gcc 版本中未实现(它在 4.4 中,不在 4.2 中,我不知道 4.3 中是否有)。
。
It is a code model issues. By default, static code is build assuming the whole program will stay in the lower 2G part of the memory address space. Code for shared libraries need to be compiled for another memory model, either PIC, or with -mcmodel=large which will compile without making that assumption.
Note that -mcmodel=large is not implemented in older gcc version (it is in 4.4, it isn't in 4.2, I don't know for 4.3).
.
这纯粹是 ABI 人强加给我们的任意要求。 x86_64 上的动态链接器无法支持非 PIC 库,没有任何逻辑原因。然而,由于 x86_64 不像 x86 那样承受如此可怕的寄存器压力(并且具有更好的 PIC 功能),因此我不知道有什么重要原因不使用 PIC。
It's purely an arbitrary requirement the ABI people have imposed on us. There's no logical reason why the dynamic linker on x86_64 couldn't support non-PIC libraries. However, since x86_64 is not under such horrible register pressure as x86 (and has better features for PIC), I don't know of any significant reason not to use PIC.