我最近正在构建一个针对x86-64架构的特定共享库(ELF),如下所示:
g++ -o binary.so -shared --no-undefined ... -lfoo -lbar
此操作失败并出现以下错误:
在制作共享对象时,不能使用对“本地符号”重新定位R_X86_64_32;用-fPIC重新编译
当然,这意味着我需要将其重建为与位置无关的代码,因此它适合链接到共享库。
但是这在x86上完全适用于完全相同的构建参数。所以问题是,x86上的重定位与x86-64有什么不同,为什么我不需要在前者上使用-fPIC
进行编译?
答案 0 :(得分:17)
我找到a nice and detailed explanation,归结为:
答案 1 :(得分:4)
这是一个代码模型问题。默认情况下,假设整个程序将保留在内存地址空间的较低2G部分,则构建静态代码。需要为另一个内存模型编译共享库代码,无论是PIC,还是使用-mcmodel = large,这将编译而不做出这样的假设。
请注意,-mcmodel = large在较旧的gcc版本中未实现(它在4.4中,它不在4.2中,我不知道4.3)。
答案 2 :(得分:0)
纯粹是ABI人强加给我们的任意要求。 x86_64上的动态链接器无法支持非PIC库,这是没有逻辑的原因。但是,由于x86_64没有像x86这样可怕的寄存压力(并且具有更好的PIC功能),我不知道有任何重要原因不使用PIC。