一尘不染

与位置无关的代码的区别:x86与x86-64

linux

我最近正在构建针对x86-64架构的特定共享库(ELF),如下所示:

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

失败并显示以下错误:

创建共享库时,不能使用针对“本地符号”的R_X86_64_32重定位;用-fPIC重新编译

当然,这意味着我需要将其重建为位置无关的代码,因此适合链接到共享库。

但这在具有完全相同的构建参数的x86上效果很好。所以问题是,x86上的重定位与x86-64有何不同?为什么我不需要-fPIC在前一个上进行编译?


阅读 359

收藏
2020-06-03

共1个答案

一尘不染

我找到了一个很好而详细的解释,可以归结为:

  1. x86-64使用IP相对偏移量来加载全局数据,而x86-32无法使用它来引用全局偏移量。
  2. IP相对偏移不适用于共享库,因为可以覆盖全局符号,因此,如果不使用PIC构建,x86-64就会崩溃。
  3. 如果使用PIC构建了x86-64,则IP相对偏移取消引用现在会产生 一个指向GOT entry的指针 ,然后将其取消引用。
  4. 但是,x86-32 已经 使用了全局偏移量的取消引用,因此将其直接转换为GOT条目。
2020-06-03