使用LLVM链接到动态库中的外部函数

问题描述

在我的项目中,我发出了LLVM IR,该IRVM可以调用动态库中的外部函数。

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

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

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

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

当我编译IR并运行它时,该过程立即崩溃。如果我声明并调用一个我不知道的废话函数,则会发生相同的行为,因此我假设正在发生的事情是未找到/链接外部函数。 (我不认为该函数本身会崩溃)。

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

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

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

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

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

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


解决方法

我发现了这一点—我不知道需要调用llvmlite.binding.load_library_permanently(filename)才能使外部符号可用。即使该库已经在内存中,仍然需要调用该函数。 (这对应于LLVM本机函数llvm::sys::DynamicLibrary::LoadLibraryPermanently())。

this answer看来,用nullptr调用上述函数将导入该过程可用的所有符号。

奇怪的是,在OSX上,我发现即使没有显式调用load_library_permanently(),外部符号仍然可用-我不确定为什么这样做(也许llvmlite的OSX构建本身发生了像上面一样用nullptr调用函数?)。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...