c - 在位置独立代码中,c 差异: x86 vs x86 64

  显示原文与译文双语对照的内容
103 2

我最近正在构建一个特定于x86-64架构的共享库( ELF ) 目标,如下所示:


g++ -o binary.so -shared --no-undefined.. . -lfoo -lbar



这里操作失败,出现以下错误:

在创建共享对象时,无法使用针对`a局部符号的重定位 R_X86_64_32 ;使用-fPIC重新编译

当然,这意味着我需要将它重新构建为位置独立的代码,因此它适合于链接到共享库。

但是在x86上,它完全可以使用相同的构建参数。 所以问题是,x86上的重定位如何与x86-64不同,为什么我不需要在前面的-fPIC 上编译?

时间: 原作者:

123 5

我发现是一个很好和详细的解释,它归结为:

  • x86-64使用相对偏移来加载全局数据,x86-32不能加载全局数据,因此取消引用全局偏移量。
  • ip相对偏移不适用于共享库,因为可以重写全局符号,因这里x86-64在不构建时会断开。
  • 如果用PIC构建了 x86-64,那么现在的相对偏移会产生 ,一个指针进入,然后被取消引用。
  • 然而,x86-32已经使用一个全局偏移的引用,所以它被直接输入到了 entry 。
原作者:
96 0

这是一个代码模型问题。 在默认情况下,static 代码的构建假定整个程序将保留在内存地址空间的2G 部分。 共享库的代码需要为另一个内存模型编译,或者使用-mcmodel=large编译,而不需要进行编译。

请注意,-mcmodel=large在旧的gcc版本( 它在 4.4,不是 4.2,我不知道 4.3 ) 中没有实现。

原作者:
...