使用LLVM-5.0我实现了一个最小的测试用例,它为在运行时返回32位整数“42”的函数创建程序集并执行它。
使用llvm::ExecutionEngine
我能够在运行时生成以下代码(与gdb一起显示):
0x7ffff7ff5000 mov $0x2a,%eax
0x7ffff7ff5005 retq
调用函数产生
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7ff5000 in ?? ()
我的工作理论是LLVM编写代码的内存页面不可执行。
这真的是DEP问题吗?如果是,我怎样才能使LLVM中的JITed函数实际可执行?
附录:实际测试用例
#include <llvm/IR/LLVMContext.h>
#include <llvm/IR/Module.h>
#include <llvm/IR/IRBuilder.h>
#include <llvm/IR/Verifier.h>
#include <llvm/ExecutionEngine/ExecutionEngine.h>
#include <llvm/Support/TargetSelect.h>
#include <iostream>
int main() {
// Initialize global state
llvm::InitializeNativeTarget();
llvm::InitializeNativeTargetAsmPrinter();
llvm::InitializeNativeTargetAsmParser();
// Initialize local state
llvm::LLVMContext context;
// Create the module that will be compiled
std::unique_ptr<llvm::Module> module(new llvm::Module("jit", context));
// Create function type
std::vector<llvm::Type*> arg_types;
llvm::FunctionType* func_type = llvm::FunctionType::get(llvm::Type::getInt32Ty(context), arg_types, false);
// Create actual function
llvm::Function* func = llvm::Function::Create(func_type, llvm::Function::LinkageTypes::ExternalLinkage, "anon", module.get());
// Define function body
llvm::IRBuilder<> builder(context);
llvm::BasicBlock *block = llvm::BasicBlock::Create(context, "entry", func);
builder.SetInsertPoint(block);
builder.CreateRet(llvm::ConstantInt::get(llvm::Type::getInt32Ty(context), 42));
// Verify function
llvm::verifyFunction(*func);
// Build the execution engine
std::string error;
llvm::EngineBuilder engine_builder(std::move(module));
engine_builder.setErrorStr(&error);
engine_builder.setEngineKind(llvm::EngineKind::JIT);
std::unique_ptr<llvm::ExecutionEngine> engine(engine_builder.create());
if (!engine) {
std::cerr << error << std::endl;
return 1;
}
// Get a pointer to the JITed function
void* jit_ptr = engine->getPointerToFunction(func);
auto function = reinterpret_cast<int32_t(*)()>(jit_ptr);
// Execute the JITed function
std::cout << function() << std::endl;
return 0;
}
答案 0 :(得分:1)
根据来源,不推荐使用方法getPointerToFunction为MCJIT执行引擎。
/// getPointerToFunction - (...)
/// This function is deprecated for the MCJIT execution engine. Use
/// getFunctionAddress instead.
virtual void *getPointerToFunction(Function *F) = 0;
因此我会使用addModule(std::move(module))
后跟getFunctionAddress(functionName)
。这应该&#34;最终确定&#34;通过更改内存的权限来生成代码。