将LLVM IR转换为Java字节码

时间:2018-07-25 17:50:09

标签: llvm llvm-clang llvm-ir java-bytecode-asm

我是初学者,想构建可将LLVM位代码转换为Java字节码的转换器。

有人可以简单地告诉我还是列出一些主要步骤来进行操作。

1 个答案:

答案 0 :(得分:4)

在我们公司(Altimesh)中,我们为CIL做过同样的事情。对于Java字节码,任务可能非常相似。

我可以告诉你这是一个漫长的任务。

第一件事: LLVM库是用C ++编写的

这意味着您要么必须学习c ++,而且必须从c ++生成 java字节码,要么将所需的符号从LLVM库导出到JNI。我强烈建议第二种选择,因为您将获得纯Java实现(并且您很快就会发现不需要LLVM API中的太多符号)。

确定了这一点后,您需要:

  1. 从文件中解析模块

这是一个简单的示例(使用llvm 3.9 API,现在已经很老了):

llvm::Module* llvm__Module_buildFromFile (llvm::LLVMContext* context, const char* filename)
    {
        llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> buf = llvm::MemoryBuffer::getFile(filename);
        llvm::SMDiagnostic diag;
        return llvm::parseIR(buf->get()->getMemBufferRef(), diag, *context).release();
    }
  1. 解析调试信息

    void llvm__DebugInfoFinder__processModule(llvm :: DebugInfoFinder * self,llvm :: Module * M) {     self-> processModule(* M); }

调试信息或元数据对于llvm来说是很痛苦的,因为它们非常频繁地更改(与说明相比)。因此,您要么必须坚持LLVM的版本(可能是一个错误的选择),要么在新的LLVM版本发布后立即更新代码。

一旦您到达那里,大部分的痛苦就在您身后,您就进入了充满乐趣的世界。

我强烈建议从非常简单的内容开始,例如简单的addition program

然后始终保持打开两个窗口,godbolt显示您输入需要解析的llvm,而Java窗口显示目标(here is an example for MSIL)。

一旦您能够编译您的第一个程序(hurrraah,我可以添加两个整数:)),您将很快要编译more stuff,并且很快您将面临两个精神错乱:

  • getelementptr。这就是在LLVM中访问数组,内存,结构...的方式。这是一个非常神奇的指令。

  • phi。 LLVM系统中的关键指令,因为它允许Single Static Assignment,这对于后端(寄存器分配器和co)非常重要。我不知道Java,但这在MSIL中显然不可用。

完成所有这些操作后,您将进入无尽痛苦的特殊情况,奇怪的C构造you didn't know about,gcc扩展等等……

无论如何,祝你好运!