Search code examples
cassemblyx86inline-assemblyfpic

Address of global symbol table (GOT) in PIC/PIE binaries


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?


Solution

  • 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.