我正在维护ioquake3中虚拟机的JIT编译器。
最近有人试图从ioquake3构建一个pie二进制,但是编译的代码广泛使用了ebx寄存器,其中pic code和pie二进制文件似乎是包含got地址的固定寄存器。
虚拟机可以在固定点上调用GCC编译的代码,因此我需要将EBX还原到GOT地址。为此,JIT-Compiler代码需要知道GOT地址,以便它可以发出将EBX恢复到该地址的代码。我想您可以直接使用类似的内联装配:
void *gotptr;
__asm__ volatile("n": "=b" (gotptr));
编译的代码是从JIT-编译器代码直接调用的,因此EBX在JIT编译中以及在VM中的调用中应相同。我的问题是:这项工作是否有效,并且有其他方法可以从C代码检索GOT地址,例如,是否定义了一个指定该地址的符号,还是有返回其函数的函数?
在系统v i386 abi中,其责任是在必要时设置eBX的函数,因此在调用pic/pie commied函数时,不需要任何需要还原它。如ABI所说:
独立于位置的代码使用
%ebx
寄存器保存地址 全球偏移表。如果功能需要全局偏移 表的地址是直接或间接的,它是负责的 计算值。