如何使用llvm生成机器代码
How to generate machine code with llvm
我目前正在使用llvm进行编译器项目。我遵循了各种教程,直到我有了一个解析器来创建语法树,然后使用提供的IRBuilder将树转换为llvm模块。
我的目标是创建一个可执行文件,但我对下一步该做什么感到困惑。我找到的所有教程都只是创建llvm模块,并使用module.dump()打印出程序集。此外,我能找到的唯一文档是针对llvm开发人员的,而不是项目的最终用户。
如果我想生成机器代码,接下来的步骤是什么?llvm-mc项目看起来可以做我想做的事,但我找不到任何文档。
也许我期待llvm做一些它没有做的事情。我的期望是,我可以构建一个模块,然后会有一个API,我可以用模块调用,并生成一个目标三元组和一个对象文件。我已经找到了关于生成JIT的文档和示例,但我对此不感兴趣。我正在寻找如何生成已编译的二进制文件。
我正在操作系统X上工作,如果这有任何影响的话。
使用llc -filetype=obj
从IR发出可链接的对象文件。您可以查看llc
的代码,以查看它为发出此类代码而进行的LLVM API调用。至少对于Mac OS X和Linux来说,以这种方式发射的对象应该非常好(即,现在这还不是"alpha质量"选项)。
然而,LLVM(还!)不包含链接器。因此,要将此对象文件实际链接到某个可执行文件或共享库,您需要使用系统链接器。请注意,即使您有一个由单个对象文件组成的可执行文件,后者也必须链接。LLVM社区的开发人员正在为LLVM开发一个真正的链接器,称为lld
。您可以访问它的页面或搜索邮件列表档案来了解它的进展。
正如您在llc指南中所读到的,它实际上只是生成程序集,然后"汇编语言输出可以通过本机汇编程序和链接器来生成本机可执行文件",例如gnu汇编程序(as
)和链接器(ld
)。
因此,这里的主要答案是使用本地工具进行组装和链接。
然而,有实验支持通过llc
:直接从IR文件生成本地对象
-filetype - Choose a file type (not all types are supported by all targets):
=asm - Emit an assembly ('.s') file
=obj - Emit a native object ('.o') file [experimental]
或者,您可以使用llvm-mc
从.s
文件进行组装:
-filetype - Choose an output file type:
=asm - Emit an assembly ('.s') file
=null - Don't emit anything (for timing purposes)
=obj - Emit a native object ('.o') file
不过,我不知道链接器。
此外,我建议查看tools/bugpoint/ToolRunner.h
文件,该文件公开了一个结合llc
和平台的本机C工具链的包装器,用于生成机器代码。从其标题评论:
此文件公开了一个围绕C平台编译器的抽象,用于编译C和汇编代码。
查看llvm-c/TargetMachine.h
:中的这些函数
/** Emits an asm or object file for the given module to the filename. This
wraps several c++ only classes (among them a file stream). Returns any
error in ErrorMessage. Use LLVMDisposeMessage to dispose the message. */
LLVMBool LLVMTargetMachineEmitToFile(LLVMTargetMachineRef T, LLVMModuleRef M,
char *Filename, LLVMCodeGenFileType codegen, char **ErrorMessage);
/** Compile the LLVM IR stored in p M and store the result in p OutMemBuf. */
LLVMBool LLVMTargetMachineEmitToMemoryBuffer(LLVMTargetMachineRef T, LLVMModuleRef M,
LLVMCodeGenFileType codegen, char** ErrorMessage, LLVMMemoryBufferRef *OutMemBuf);
要运行示例BrainF
程序,请编译它并运行:
echo ,. > test.bf
./BrainF test.bf -o test.bc
llc -filetype=obj test.bc
gcc test.o -o a.out
./a.out
然后键入一个字母并按Enter键。它应该回你那封信。(,.
就是这么做的。)
以上内容已使用LLVM 3.5.0版本进行了测试。
- 处理小于cpu数据总线的数据类型.(c++转换为机器代码)
- 使用不同的链接器会产生不同的机器代码吗
- objdump 不显示机器代码,但显示 ASM
- 从.o目标文件中提取函数的原始机器代码?
- 我在区分源代码、目标代码、汇编代码和机器代码时感到困惑
- 如果C++编译为机器代码,为什么我们需要安装"运行时"?
- 是否可以执行存储在变量中的机器代码
- "Double or Nothing"赌博机器代码无法超过15组合
- 如何在 c++ 中将机器代码作为函数运行
- 可以从文件执行机器代码吗?
- 如何将x64机器代码写入虚拟内存并在C++中为Windows执行
- 如何将高级/低级编程代码直接转换为机器代码
- (如何)我可以使用LLVM机器代码分析器预测代码片段的运行时间
- 如何使用llvm生成机器代码
- 使用LLVM生成纯机器代码
- 注释会被翻译成机器代码吗?C++
- 如何使用c++执行附加在可执行文件末尾的机器代码
- 如何从机器代码中恢复C++尝试/抛出/捕获块长度和地址
- 是否有编译器可以编译为机器代码的 C C++ C# 编译器
- C++ - 极其奇怪的机器代码行为