I am maintaining the JIT compiler for the virtual machine in ioquake3.
Recently someone tried to build a PIE binary from ioquake3, however compiled code makes extensive use of the EBX register which in PIC code and thus PIE binaries seems to be a fixed register containing the GOT address.
The virtual machine may call into GCC-compiled code at a fixed point so there I will need to restore EBX to the GOT address. For that the JIT-compiler code needs to know the GOT address so that it can emit code that restores EBX to that address. I imagine you could directly use inline assembly like so:
void *gotptr;
__asm__ volatile("\n": "=b" (gotptr));
Compiled code is directly called from the JIT-compiler code so EBX should be the same at JIT compile and at the call into the VM. My question is: would this work, and is there a different way to retrieve the GOT address from C code, for instance, is there a symbol defined that specifies that address, or is there a function that returns it?
In the System V i386 ABI its the responsibility of the function being called to set EBX if necessary, so there shouldn't be any need to restore it when calling PIC/PIE compiled functions. As the ABI states:
Position-independent code uses the
%ebx
register to hold the address of the global offset table. If a function needs the global offset table’s address, either directly or indirectly, it is responsible for computing the value.