与 LLVM 的动态链接

Posted

技术标签:

【中文标题】与 LLVM 的动态链接【英文标题】:dynamic linking with LLVM 【发布时间】:2012-06-04 16:02:12 【问题描述】:

我想在一个模块中执行函数,这个模块将在其他模块中解决依赖关系。模块可能会改变(动态编译环境),所以我不希望将所有依赖项链接到一个单一的模块中,也就是说,如果可以避免的话

我希望使用Linker::linkModules 但这总是对源模块具有破坏性。这对于一个依赖于一个模块的模块来说是可以的,因为如果那个模块发生了变化,那没什么大不了的,但是重建和重新链接 N-1 个模块不是因为一个模块发生了变化而没有变化的过度吗?

我想知道是否有可以用于 JIT 执行的非破坏性版本的 linkModules。

【问题讨论】:

【参考方案1】:

试试这个:

Linker::LinkModules(destinationModule, sourceModule, Linker::PreserveSource, &error);

如果你传递Linker::PreserveSource而不是Linker::DestroySource,你可以在调用后继续使用sourceModule

【讨论】:

【参考方案2】:

我们在 Fabric Engine 产品 (http://fabricengine.com/) 内的动态编译环境中做了类似的事情。 LLVM 目前还不能很好地适应这种复杂的“JIT”环境,但我们设法通过额外的间接级别(即双指针)链接使其工作,然后将 llvm::MemoryManager 子类化以重载 llvm: :MemoryManager::getPointerToNamedFunction 在模块之间全局解析符号。通过使用双指针,您可以更改一个模块而不更改任何其他模块。你必须稍微小心一点,但还不错。

【讨论】:

【参考方案3】:

我认为这不可能是您描述问题的方式。

在您的理想解决方案中,如果模块 AB 被链接,更改 B 将立即在 A 中观察到?

如果是这样的话,我认为这是不可能的。 (尝试链接B后查看A的内容。B的符号已复制到A中)

如果您只是想保留B 中的信息,您可以先复制Bllvm::CloneModule,然后将结果传递给Linker::linkModules

【讨论】:

与普通共享库一样,如果Bchanges,A 仍需要重新链接到新的 B。我的观点是:如果 A 与 B0 链接,B1 ...BN 并且其中一个发生了变化,我只需要将引用重新链接到那个,因为其余的没有改变。当前的 linkModules 用作静态链接器(将所有内容复制到目标模块中) Linux 内核及其模块允许这样的事情(卸载模块,重新加载新版本)。但是那里的进程在内核的控制之下,并且有适当的互锁机制来确保代码没有被使用。

以上是关于与 LLVM 的动态链接的主要内容,如果未能解决你的问题,请参考以下文章

静态链接与动态链接

静态链接与动态链接

[转载] 动态链接库dll的 静态加载 与 动态加载

Linux动态链接和静态链接简析

静态链接与动态链接

makefile与动态链接库案例分析——动态库链接动态库