【问题标题】:How to generate machine code with llvm如何使用 llvm 生成机器码
【发布时间】:2012-11-07 23:48:49
【问题描述】:

我目前正在使用 llvm 进行编译器项目。我遵循了各种教程,直到我有一个解析器来创建语法树,然后使用提供的 IRBuilder 将树转换为 llvm 模块。

我的目标是创建一个可执行文件,但我对下一步该做什么感到困惑。我找到的所有教程都只是创建 llvm 模块并使用 Module.dump() 打印出程序集。此外,我能找到的唯一文档是针对 llvm 开发人员的,而不是针对项目的最终用户的。

如果我想生成机器码,接下来的步骤是什么? llvm-mc 项目看起来可以做我想做的事,但我找不到任何关于它的文档。

也许我期望 llvm 做一些它没有做的事情。我的期望是我可以构建一个模块,然后会有一个我可以用模块调用的 API,一个目标三元组和一个目标文件将被生成。我找到了有关生成 JIT 的文档和示例,但我对此不感兴趣。我正在寻找如何生成已编译的二进制文件。

我正在开发 OS X,如果这有什么影响的话。

【问题讨论】:

    标签: c++ llvm machine-code


    【解决方案1】:

    正如您在the llc guide 上看到的那样,它确实只是为了生成程序集,然后“然后可以通过本机汇编程序和链接器传递汇编语言输出以生成本机可执行文件” - 例如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 和汇编代码。

    【讨论】:

      【解决方案2】:

      使用llc -filetype=obj 从您的 IR 发出可链接的目标文件。您可以查看llc 的代码以查看它发出此类代码的 LLVM API 调用。至少对于 Mac OS X 和 Linux,以这种方式发出的对象应该是相当不错的(即,现在这不是“alpha 质量”选项)。

      但是,LLVM 不包含链接器(还没有!)。因此,要将这个目标文件实际链接到某个可执行文件或共享库中,您需要使用系统链接器。请注意,即使您有一个由单个目标文件组成的可执行文件,也必须链接后者。 LLVM 社区的开发人员正在为 LLVM 开发一个真正的链接器,称为lld。您可以访问its page 或搜索邮件列表存档以跟踪其进度。

      【讨论】:

        【解决方案3】:

        要运行示例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 版测试的。

        【讨论】:

          【解决方案4】:

          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);
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2019-03-05
            • 2014-06-23
            • 1970-01-01
            相关资源
            最近更新 更多