我是初学者,想构建可将LLVM位代码转换为Java字节码的转换器。
有人可以简单地告诉我还是列出一些主要步骤来进行操作。
答案 0 :(得分:4)
在我们公司(Altimesh)中,我们为CIL做过同样的事情。对于Java字节码,任务可能非常相似。
我可以告诉你这是一个漫长的任务。
第一件事: LLVM库是用C ++编写的
这意味着您要么必须学习c ++,而且必须从c ++生成 java字节码,要么将所需的符号从LLVM库导出到JNI。我强烈建议第二种选择,因为您将获得纯Java实现(并且您很快就会发现不需要LLVM API中的太多符号)。
确定了这一点后,您需要:
这是一个简单的示例(使用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();
}
解析调试信息
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扩展等等……
无论如何,祝你好运!