Force TEXT relocations only rather than GOT/PLT

Hello!

I’m looking into some research regarding relocations and I was wondering if anyone had insights if I could make clang force-emit text relocations for symbols in PIE/PIC code rather than either a PLT/GOT or GOT (-fno-plt). I’m happy to restrict myself to a single target if it exists there and emulate via qemu.

Thank you!

On my x86 system, for PIC code, we have to use the GOT since our memory model is such that code lives in 64-bit address space but our static data lives in 32-bit address space. You either need the GOT to reach that far (or use the extreme large-model on x86).

I see –

I’m also looking into R_X86_64_64 relocations which I think are produced for non-PIE.
They seem analogous to as if we had done the text relocations rather than GOT/PLT?

A dynamic relocation applied on a non-writable section is called a text relocation.
(Copy relocations, canonical PLT entries and protected visibility | MaskRay)

Whether text relocations are needed is decided by both compiler code generation (-fPIC/-fno-pic, -fdirect-access-external-data are relevant) and linker behavior (-no-pie/-pie/-shared are relevant).

To emit direct access relocations (primarily absolute R_X86_64_32 and PC-relative R_X86_64_PC32), you can specify -fdirect-access-external-data with -fpie or just use -fno-pic (⚙ D92633 Add -f[no-]direct-access-external-data to supersede -mpie-copy-relocations). On COFF, this is the default unless you specify dllimport.

However, linkers largely only emit text relocations for very few scenarios on ELF platforms.
Copy relocations and canonical PLT entries are used for many scenarios.

Grepping -z notext in lld/text/ELF may yield some results.
I don’t think we would introduce new mode to upstream linkers to allow more text relocations.

From Linker notes on PE/COFF | MaskRay
MinGW implements runtime pseudo relocations to patch the text section so that absolute pointers and relative offsets to the symbol will be rewritten to bind to the actual definition.

movq var(%rip), %rax # the runtime will rewrite this to point to the definition in b.dll

If the variable is defined out of the ±2GiB range from the current location, the runtime pseudo relocation can’t fix the issue. See crt: Check pseudo relocations for overflows and error out clearly.