force gcc to emit RIP-relative code only?
Posted: Sun Nov 20, 2016 8:23 am
I am on the x86_64.
My ELF dynamic linker is part of the C library, and currently I'm using a pretty dirty way to load it.
The kernel loads libc from the initrd, and performs relocations to move it to 1GB. It then maps the code segment into the address space of every executable that uses libraries.
Of course, libc is compiled as position-indepent code and hence uses GOT/PLT, which allows for the relocation to work.
However, libc does not refer to any external libraries at all, so the PLT/GOT are not actually needed. Is there a way to force GCC to assume that all symbols will be local after the final link, and hence only use RIP-relative addressing? This will mean that the kernel will not have to perform any relocations at all.
EDIT: I now realise that GCC seems to be using RIP-relative addressing anyway, and with "-fPIC" it just uses GOT/PLT for indirection. However, the lniker still complains about bad relocation values for R_X86_64_PC32, even if all the symbols are locally visible, which does not make sense to me. Is there a way to force the static linker to resolve all relocations and not emit any for the dynamic linker, since the distance between all symbols used is known to it?
My ELF dynamic linker is part of the C library, and currently I'm using a pretty dirty way to load it.
The kernel loads libc from the initrd, and performs relocations to move it to 1GB. It then maps the code segment into the address space of every executable that uses libraries.
Of course, libc is compiled as position-indepent code and hence uses GOT/PLT, which allows for the relocation to work.
However, libc does not refer to any external libraries at all, so the PLT/GOT are not actually needed. Is there a way to force GCC to assume that all symbols will be local after the final link, and hence only use RIP-relative addressing? This will mean that the kernel will not have to perform any relocations at all.
EDIT: I now realise that GCC seems to be using RIP-relative addressing anyway, and with "-fPIC" it just uses GOT/PLT for indirection. However, the lniker still complains about bad relocation values for R_X86_64_PC32, even if all the symbols are locally visible, which does not make sense to me. Is there a way to force the static linker to resolve all relocations and not emit any for the dynamic linker, since the distance between all symbols used is known to it?