代码之家  ›  专栏  ›  技术社区  ›  Alex B

位置无关代码的差异:x86与x86-64

  •  24
  • Alex B  · 技术社区  · 14 年前

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

    此操作失败,错误如下:

    创建共享对象时,不能使用针对“本地符号”的重定位R\u X86\u 64\u 32;用-fPIC重新编译

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

    但在具有完全相同的构建参数的x86上,这种方法非常有效。所以问题是,x86上的重定位与x86-64有什么不同,为什么我不需要使用 -fPIC

    3 回复  |  直到 14 年前
        1
  •  20
  •   Alex B    14 年前

    我找到了 a nice and detailed explanation

    1. x86-64使用IP相对偏移量加载全局数据,而x86-32不能,因此它取消了对全局偏移量的引用。
    2. IP相对偏移量不适用于共享库,因为全局符号可以被重写,所以x86-64在不使用PIC构建时会崩溃。
    3. 如果x86-64是用PIC构建的,那么IP相对偏移取消引用现在会产生 指向get entry的指针 ,然后取消引用。
    4. 但是x86-32, 已经 使用全局偏移量的解引用,因此直接将其转换为get条目。
        2
  •  4
  •   AProgrammer    14 年前

    这是一个代码模型问题。默认情况下,静态代码的构建假设整个程序将停留在内存地址空间的较低2G部分。共享库的代码需要为另一个内存模型(PIC或-mcmodel=large)编译,它将编译而不做这种假设。

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

        3
  •  1
  •   R.. GitHub STOP HELPING ICE    14 年前