0

在我的项目中,我发出 LLVM IR,它调用动态库中的外部函数。

我声明我的外部函数,如:

declare %"my_type"* @"my_function"()

在外部库中,函数声明如下:

extern "C" {
    my_type* my_function();
}

当我编译 IR 并运行它时,该过程立即崩溃。如果我声明并调用一个我知道不存在的无意义函数,也会发生同样的行为,所以我假设正在发生的事情是没有找到/链接外部函数。(我不认为函数本身会崩溃)。

我正在使用 Python 的llvmlite库来执行此任务,并且在我 JIT 并调用我的 LLVM IR 的同一进程中,我导入了另一个需要外部动态库的 python 库;所以我假设该库已加载并在内存中。

我用来编译和执行我的 LLVM 代码的过程与本文档中的基本相同,除了 IR 声明并调用了一个外部函数。我已经尝试过调用cos(),就像在Kaleidoscope 教程中一样,并且成功了,所以我不确定我自己的库函数有什么不同。

我尝试在函数名称的开头添加下划线,但得到了相同的结果。(我需要在 LLVM 函数声明中添加下划线吗?)

  • 如何验证我的假设,即由于找不到命名函数而导致进程崩溃?
  • 如何诊断为什么找不到该功能?
  • 为了从 LLVM 代码中使用动态库中的外部函数,我需要做什么?

编辑:似乎确实很难将函数指针指向我的外部函数。如果我尝试通过替换我的调用来仅打印函数地址%"foo" = ptrtoint %"my_type"* ()* @"my_function" to i64并返回/打印结果,它仍然会出现段错误。仅仅试图获取指针就足以导致崩溃!为什么会这样,我该如何解决?

编辑:也忘了提——这是在 Ubuntu 上(在 Docker 容器中,在 OSX 上)。


4

1 回答 1

1

我想通了——我错过了我需要调用llvmlite.binding.load_library_permanently(filename)才能使外部符号可用的地方。即使库已经在内存中,仍然需要调用该函数。(这对应于 LLVM 本机函数llvm::sys::DynamicLibrary::LoadLibraryPermanently())。

这个答案看来,调用上述函数nullptr将导入进程可用的所有符号。

奇怪的是,在 OSX 上,我发现即使load_library_permanently()没有显式调用外部符号也是可用的——我不确定这是为什么(也许 OSXllvmlite本身的构建碰巧用 调用了函数nullptr,如上所述?)。

于 2020-09-30T21:36:50.943 回答