与 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】:我认为这不可能是您描述问题的方式。
在您的理想解决方案中,如果模块 A
和 B
被链接,更改 B
将立即在 A
中观察到?
如果是这样的话,我认为这是不可能的。 (尝试链接B
后查看A
的内容。B
的符号已复制到A
中)
如果您只是想保留B
中的信息,您可以先复制B
和llvm::CloneModule
,然后将结果传递给Linker::linkModules
。
【讨论】:
与普通共享库一样,如果B
changes,A
仍需要重新链接到新的 B。我的观点是:如果 A 与 B0
链接,B1
...BN
并且其中一个发生了变化,我只需要将引用重新链接到那个,因为其余的没有改变。当前的 linkModules 用作静态链接器(将所有内容复制到目标模块中)
Linux 内核及其模块允许这样的事情(卸载模块,重新加载新版本)。但是那里的进程在内核的控制之下,并且有适当的互锁机制来确保代码没有被使用。以上是关于与 LLVM 的动态链接的主要内容,如果未能解决你的问题,请参考以下文章