我正在维护JIT compiler for the virtual machine in ioquake3。
最近有人试图从ioquake3构建一个PIE二进制文件,但编译代码大量使用了PIC代码中的EBX寄存器,因此PIE二进制文件似乎是一个包含GOT地址的固定寄存器。
虚拟机可能会在固定点调用GCC编译的代码,因此我需要将EBX恢复到GOT地址。 为此,JIT编译器代码需要知道GOT地址,以便它可以发出将EBX恢复到该地址的代码。 我想你可以像这样直接使用内联汇编:
void *gotptr;
__asm__ volatile("\n": "=b" (gotptr));
编译代码直接从JIT编译器代码调用,因此EBX在JIT编译和调用VM时应该是相同的。我的问题是:这是否有效,是否有一种不同的方法从C代码中检索GOT地址,例如,是否有一个符号定义了指定该地址,或者是否有一个返回它的函数?
答案 0 :(得分:3)
在System V i386 ABI中,如果需要,调用函数的责任是设置EBX,因此在调用PIC / PIE编译函数时不需要恢复它。正如ABI所说:
与位置无关的代码使用
%ebx
寄存器来保存地址 全局偏移表的。如果函数需要全局偏移量 表的地址,无论是直接还是间接,它负责 计算价值。