LLVM IR,简单程序给出段错误

LLVM IR, simple program gives segfault

我在运行时生成了以下 llvm ir,我希望立即执行该函数

;other declarations/functions

define %gen__struct__81ty_struct.catch_val @gen__fun__115(void**) {
entry:
  %1 = getelementptr void*, void** %0, i32 0
  %2 = load void*, void** %1, align 8
  %3 = bitcast void* %2 to i64*
  store i64 1, i64* %3, align 8
  %4 = load i64, i64* %3, align 8
  %5 = getelementptr void*, void** %0, i32 1
  %6 = load void*, void** %5, align 8
  %7 = bitcast void* %6 to i64*
  store i64 1, i64* %7, align 8
  %8 = load i64, i64* %7, align 8
  %9 = getelementptr void*, void** %0, i32 2
  %10 = load void*, void** %9, align 8
  %11 = bitcast void* %10 to i64*
  store i64 1, i64* %11, align 8
  ret %gen__struct__81ty_struct.catch_val zeroinitializer
}

然后我使用 kaleidoscope jit 和下面的 C++ 代码编译并执行了上面的函数,但我一直遇到段错误。

    Function* out = 0;
    //code that generates the function ...

    runFunc fptr = 0;
    jit->addModule(std::move(gblDevice->lmod));
    fptr = (runFunc)jit->getPointerToFunction(out);

    vector<void*> params;
    uint64_t a = 0;
    uint64_t b = 0;
    uint64_t c = 0;
    params.push_back(&a);
    params.push_back(&b);
    params.push_back(&c);

    catch_val_pt cval = fptr(&params[0]);

我已经尝试了几个小时来弄清楚上面的代码有什么问题,但一切似乎都已检查出来。

getPointerToFunction 函数是。

class OrcJIT {
// ...
JITSymbol findSymbol(const std::string Name) {
    std::string MangledName;
    raw_string_ostream MangledNameStream(MangledName);
    Mangler::getNameWithPrefix(MangledNameStream, Name, DL);
    return CODLayer.findSymbol(MangledNameStream.str(), true);
}

inline void* getPointerToFunction(Function* F) {
    return (void*)findSymbol(F->getName().data()).getAddress();
}
//...
}

最后答案很简单

llvm 执行 return 值的方式与 gcc 执行 return 值的方式之间肯定存在二进制不兼容。简短的回答是 gen__struct__81ty_struct.catch_val return 值导致段错误。

简单地放在生成的函数中,您需要 return 通过传递给生成函数的指针将其复制到结构。除了最简单的情况(又名 int),您不能依赖生成的函数匹配的 return 值。