我有一个我写的程序,它使用LLVM 3.5作为JIT编译器,我正在尝试更新以在LLVM 3.7中使用MCJIT . 我主要使用它,但我很难重现我用LLVM 3.5实现的一个仅调试功能 .
我希望能够看到JIT进程生成的主机代码(例如x86,x64或ARM,而不是LLVM IR);在调试版本中,我在程序运行时将其记录下来 . 使用LLVM 3.5,我可以通过调用ExecutionEngine :: runJITOnFunction()来填充llvm :: MachineCodeInfo对象,它为我提供了生成代码的起始地址 and size . 然后我可以反汇编代码 .
我似乎无法在MCJIT中找到任何等效物 . 我可以得到函数的起始地址(例如通过getPointerToFunction())但不是大小 .
我见过Disassemble Memory但除了在答案中没有那么多细节之外,它似乎更多的是关于如何反汇编一系列字节 . 我知道怎么做,我的问题是:我怎样才能掌握字节序列?
如果它有助于使其更具体,请将此问题重新解释为:“如何扩展示例Kaleidoscope JIT以显示它生成的机器代码(x86,ARM等),而不仅仅是LLVM IR?”
谢谢 .
2 回答
这里至少有两个选项 .
将内存管理器实例传递给EngineBuilder:
现在通过这些回调,您可以控制发出代码的内存 . (并且 size 直接传递给您的方法) . 只需记住为代码段分配的缓冲区的地址,并在gdb中停止程序并反汇编内存(或将其转储到某处或甚至使用LLVM的反汇编程序) .
llc
并使用适当的选项(优化级别等) . 正如我所看到的那样,MCJIT被调用是出于某种原因,原因在于它重用了现有的代码生成模块(与llc相同) .包括以下 Headers
llvm/Object/SymbolSize.h
,并使用函数llvm::object::computeSymbolSizes(ObjectFile&)
. 您需要以某种方式获取ObjectFile
的实例 .要获得该实例,您可以执行以下操作:
声明一个被调用的类,将
Module
转换为ObjectFile
,类似于:class ModuleToObjectFileCompiler { ... // Compile a Module to an ObjectFile. llvm::object::OwningBinary<llvm::object::ObjectFile> operator() (llvm::Module&); };
要实现
ModuleToObjectFileCompiler
的operator()
,请查看llvm/ExecutionEngine/Orc/CompileUtils.h
,其中定义了类SimpleCompiler
.为
llvm::orc::IRCompileLayer
的实例提供ModuleToObjectFileCompiler
的实例,例如:new llvm::orc::IRCompileLayer <llvm::orc::ObjectLinkingLayer <llvm::orc::DoNothingOnNotifyLoaded> > (_object_layer, _module_to_object_file);
operator()
ModuleToObjectFileCompiler
收到ObjectFile
的实例,您可以将其提供给computeSymbolSizes()
. 然后检查返回的std::vector
以找出Module
中定义的所有符号的大小(以字节为单位) . 保存您感兴趣的符号的信息 . 这就是全部 .