差异位置无关code:86 VS X86-64 [英] Difference in position-independent code: x86 vs x86-64
问题描述
我最近针对建设x86-64架构有一定的共享库(ELF),像这样的:
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:
创建共享对象时对`局部符号搬迁R_X86_64_32不能使用;与-fPIC编译
relocation R_X86_64_32 against `a local symbol' can not be used when making a shared object; recompile with -fPIC
当然,这意味着我需要重建它作为独立的位置code,所以它适合用于链接到共享库。
Of course, it means I need to rebuild it as position-independent code, so it's suitable for linking into a shared library.
但是,这工作得很好在x86上使用完全相同的构建参数。所以,问题是,如何重新定位是在x86来自不同x86-64的,为什么不让我需要 -fPIC
编译于前者?
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?
推荐答案
我已经找到一个漂亮和详细的解释,这可以归结为:
I have found a nice and detailed explanation, which boils down to:
- X86-64使用IP-相对偏移加载全局数据,X86-32不能,所以它解引用全局偏移。
- IP-相对偏移共享库是不行的,因为全局符号可以被覆盖,所以X86-64发生故障时与PIC不建。
- 如果X86-64与PIC建成,IP-相对偏移解引用,现在产量的的指针,GOT条目的,然后再解除引用。
- X86-32,然而,的已的使用全局的解引用抵消,因此它变成直接GOT条目。
- x86-64 uses IP-relative offset to load global data, x86-32 cannot, so it dereferences a global offset.
- IP-relative offset does not work for shared libraries, because global symbols can be overridden, so x86-64 breaks down when not built with PIC.
- If x86-64 built with PIC, the IP-relative offset dereference now yields a pointer to GOT entry, which is then dereferenced.
- x86-32, however, already uses a dereference of a global offset, so it is turned into GOT entry directly.
这篇关于差异位置无关code:86 VS X86-64的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!