我有一个想法是将C ++编译为二进制文件,将二进制文件存储在堆上并执行它。我正在考虑对Google Native Client这样的特定架构进行编译的一个实现,然后知道我编译的架构,在运行时使用相同或不同的编译器 - 在我的程序中编译一个"片断"或者"脚本"并将机器代码输出到堆上分配的内存。然后将函数指针指向正确的位置并运行它。 我的问题是,独立于编译器,如果将C ++编译为相同的架构,生成的二进制文件将具有相同的ABI,因此具有可调用的函数(调用约定)/任何类型的入口点?一些灵感来自像this这样的项目,但我希望在某种程度上独立于平台(我的意思是我可以编译到体系结构,我知道我在构建什么样的体系结构),编译器独立的方式在运行时工作 - 时间。
我想到的一个可能的实现只是关注LLVM IR代码,换句话说,只需要获取IR代码,组装它(到正确的指令集/体系结构),然后将二进制文件写入堆中,函数指针指向的入口点,例如(伪代码):
typedef unsigned short( * )( int ) ENTRY_POINT_T;
ENTRY_POINT_T Inject( Binary code )
{
void* block = malloc( sizeof( code ) );
*( ( Binary* ) block ) = code;
ENTRY_POINT_T entryPoint = ( ENTRY_POINT_T* ) block;
return entryPoint;
}
#ifdef x86
#define ARC "x86"
#endif
#ifdef PowerPC
#defnie ARC "PowerPC"
#endif
int main()
{
Binary executableCode = llvm.assemble( irCodeString, "-" + ARC );
auto entry = Inject( executableCode );
int result = entry( 0 );
std::cout << result << "\n";
return 0;
}
作为旁注,llvm中的compiler-rt模块看起来很有用(以及解析器)。