Rust + LLVM ORC JIT找不到符号地址

时间:2018-04-16 21:48:20

标签: rust llvm llvm-c++-api

我一直在尝试使用Rust中LLVM C绑定的ORC JIT编译器,但我一直遇到LLVMOrcGetSymbolAddress无法找到我的函数run的符号的问题。我提供的模块。下面的代码结合了我的代码中最重要的部分,遗憾的是它们不起作用。一切顺利,直到foo的最后一部分,由于找不到该函数,因此返回错误。该函数肯定在模块中,因为LLVMGetNamedFunction能够找到它,但不知何故,ORC引擎无法看到它。谁能看到我做错了什么?我正在使用LLVM 6.0和llvm-sys Rust绑定。如果我使用MCJIT但是我需要ORC进行延迟编译,一切正常。

fn foo(module: LLVMModuleRef) -> Result<I64Func, LlvmError> {
    let def_triple = LLVMGetDefaultTargetTriple();
    let mut target_ref = ptr::null_mut();
    let mut error_str = ptr::null_mut();

    // Get target from default triple
    if LLVMGetTargetFromTriple(def_triple, &mut target_ref, &mut error_str) != 0 {
        let msg = format!("Creating target from triple failed: {}", CStr::from_ptr(error_str).to_str().unwrap());
        LLVMDisposeMessage(def_triple);
        LLVMDisposeMessage(error_str);
        return Err(LlvmError(msg));
    }

    // Check if JIT is available
    if LLVMTargetHasJIT(target_ref) == 0 {
        let msg = format!("Cannot do JIT on this platform");
        LLVMDisposeMessage(def_triple);
        return Err(LlvmError(msg));
    }

    // Create target machine
    let tm_ref = LLVMCreateTargetMachine(target_ref, 
                                         def_triple,
                                         CString::new("").unwrap().as_ptr(), 
                                         CString::new("").unwrap().as_ptr(),
                                         llvm_opt_level(optimization_level)?,
                                         LLVMRelocMode::LLVMRelocDefault,
                                         LLVMCodeModel::LLVMCodeModelJITDefault);
    LLVMDisposeMessage(def_triple);
    let engine = LLVMOrcCreateInstance(tm_ref);

    // Add eagerly compiled IR
    let mut handle = LLVMOrcModuleHandle::default();
    let shared_module = LLVMOrcMakeSharedModule(module);
    let ctx = engine as *mut libc::c_void;
    map_orc_err(engine, LLVMOrcAddEagerlyCompiledIR(engine, 
                                                    &mut handle, 
                                                    shared_module, 
                                                    symbol_resolver_callback, 
                                                    ctx))?;

    // Find function named 'run'
    let c_name = CString::new("run").unwrap().as_ptr();
    let mut func_addr = LLVMOrcTargetAddress::default();
    map_orc_err(engine, LLVMOrcGetSymbolAddress(engine, &mut func_addr, c_name))?;
    if func_addr == 0 {
        // This errors always gets thrown
        return Err(LlvmError(format!("No function named {} in module", name)));
    }
    let function: I64Func = mem::transmute(func_addr);

    Ok(function)
}

extern "C" fn symbol_resolver_callback(symbol: *const libc::c_char, ctx: *mut libc::c_void) -> LLVMOrcTargetAddress {
    let mut address = LLVMOrcTargetAddress::default();
    let engine: LLVMOrcJITStackRef = ctx as LLVMOrcJITStackRef;

    unsafe { LLVMOrcGetSymbolAddress(engine, &mut address, symbol) };

    address
}

unsafe fn map_orc_err(engine: LLVMOrcJITStackRef, error_code: LLVMOrcErrorCode) -> Result<(), LlvmError> {
    match error_code {
        LLVMOrcErrorCode::LLVMOrcErrSuccess => Ok(()),
        LLVMOrcErrorCode::LLVMOrcErrGeneric => {
            let c_str: &CStr = CStr::from_ptr(LLVMOrcGetErrorMsg(engine));
            let str_slice: &str = c_str.to_str().unwrap();
            let str_buf: String = str_slice.to_owned();
            Err(LlvmError(str_buf))
        }
    }
}
编辑:我尝试降级到LLVM 4.0只是为了看看可能会产生什么影响。我仍然无法解析该函数​​,但现在我收到一个断言错误:

Assertion failed: (!Name.empty() && "getNameWithPrefix requires non-empty name"), function getNameWithPrefixImpl, file /tmp/llvm-4.0-20180412-49671-1pw0nxu/llvm-4.0.1.src/lib/IR/Mangler.cpp, line 37.

编辑2:下面是引擎无法找到功能地址的一些基本IR:

define i64 @bar(i64 %arg) {
    %1 = add i64 %arg, 1
    ret i64 %1
}

define i64 @run(i64 %arg) {
    %1 = add i64 %arg, 1
    %2 = call i64 @bar(i64 %1)
    ret i64 %2
}

0 个答案:

没有答案