PIC/PIE 二进制文件中全局符号 table (GOT) 的地址
Address of global symbol table (GOT) in PIC/PIE binaries
我正在维护 JIT compiler for the virtual machine in ioquake3。
最近有人试图从 ioquake3 构建一个 PIE 二进制文件,但是编译后的代码广泛使用了 EBX 寄存器,在 PIC 代码中,因此 PIE 二进制文件似乎是一个包含 GOT 地址的固定寄存器。
虚拟机可能会在固定点调用 GCC 编译的代码,因此我需要将 EBX 恢复到 GOT 地址。
为此,JIT 编译器代码需要知道 GOT 地址,以便它可以发出将 EBX 恢复到该地址的代码。
我想你可以像这样直接使用内联汇编:
void *gotptr;
__asm__ volatile("\n": "=b" (gotptr));
编译代码直接从 JIT 编译器代码调用,因此 EBX 在 JIT 编译和调用 VM 时应该相同。我的问题是:这行得通吗,是否有不同的方法从 C 代码中检索 GOT 地址,例如,是否定义了一个符号来指定该地址,或者是否有一个函数 returns 它?
在 System V i386 ABI 中,调用函数的职责是在必要时设置 EBX,因此在调用 PIC/PIE 编译函数时不需要恢复它。正如 ABI 所述:
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.
我正在维护 JIT compiler for the virtual machine in ioquake3。
最近有人试图从 ioquake3 构建一个 PIE 二进制文件,但是编译后的代码广泛使用了 EBX 寄存器,在 PIC 代码中,因此 PIE 二进制文件似乎是一个包含 GOT 地址的固定寄存器。
虚拟机可能会在固定点调用 GCC 编译的代码,因此我需要将 EBX 恢复到 GOT 地址。 为此,JIT 编译器代码需要知道 GOT 地址,以便它可以发出将 EBX 恢复到该地址的代码。 我想你可以像这样直接使用内联汇编:
void *gotptr;
__asm__ volatile("\n": "=b" (gotptr));
编译代码直接从 JIT 编译器代码调用,因此 EBX 在 JIT 编译和调用 VM 时应该相同。我的问题是:这行得通吗,是否有不同的方法从 C 代码中检索 GOT 地址,例如,是否定义了一个符号来指定该地址,或者是否有一个函数 returns 它?
在 System V i386 ABI 中,调用函数的职责是在必要时设置 EBX,因此在调用 PIC/PIE 编译函数时不需要恢复它。正如 ABI 所述:
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.