2017-10-23 2 views
1

LLVM-5.0 사용 런타임에 32 비트 정수 "42"를 반환하는 함수에 대한 어셈블리를 생성하고 실행하는 최소 테스트 케이스를 구현했습니다.LLVM에서 JITed 함수를 실행할 수 없습니다.

Program received signal SIGSEGV, Segmentation fault. 
0x00007ffff7ff5000 in ??() 

내 작업 이론이 메모리 페이지 LLVM 쓴 것입니다 기능 수율을 호출

0x7ffff7ff5000 mov $0x2a,%eax                                            
0x7ffff7ff5005 retq 

:

llvm::ExecutionEngine 사용 나는 (GDB로 표시) 실행시 다음과 같은 코드를 생성 할 수 있었다 코드가 실행 가능하지 않습니다.

정말 DEP 문제입니까? 그렇다면 실제로 LLVM에서 JITed 함수를 실제로 실행 가능하게 만들 수 있습니까?

부록 : 메소드 getPointerToFunction는 소스에 따른 MCJIT 실행 엔진을 위해 사용되지 않으며 실제 테스트 케이스

#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; 
} 

답변

1

.

/// getPointerToFunction - (...) 
    /// This function is deprecated for the MCJIT execution engine. Use 
    /// getFunctionAddress instead. 
    virtual void *getPointerToFunction(Function *F) = 0; 

그러므로 나는 getFunctionAddress(functionName) 다음 addModule(std::move(module))을 사용합니다. 이렇게하면 메모리 사용 권한을 변경하여 코드 생성을 "완료"해야합니다.

관련 문제