Trying to compile non-PIC code into a shared library on x64 with
gcc results in an error, something like:
/usr/bin/ld: /tmp/ccQ2ttcT.o: relocation R_X86_64_32 against `a local symbol' can not be used when making a shared object; recompile with -fPIC
This question is about why this is so. I know that x64 has RIP-relative addressing which was designed to make PIC code more efficient. However, this doesn't mean load-time relocation can't be (in theory) applied to such code.
Some online sources, including this one (which is widely quoted on this issue) claim that there's some inherent limitation prohibiting non-PIC code in shared libs, because of RIP-relative addressing. I don't understand why this is true.
Consider "old x86" - a
call instruction also has an IP-relative operand. And yet, x86 code with
call in it compiles just fine into a shared lib without PIC, but using the load-time relocation
R_386_PC32. Can't the same be done for the data RIP-relative addressing in x64?
Note that I fully understand the benefits of PIC code, and the performance penalty RIP-relative addressing helps alleviate. Still, I'm curious about the reason for not allowing using non-PIC code. Is there a real technical reasoning behind it, or is it just to encourage writing PIC code?