You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于LLVM获取机器码级别的控制流图(CFG)?

获取LLVM机器码级别的控制流图(CFG)的可行方法

当然有靠谱的办法!LLVM在后端代码生成的整个流程中都维护着机器码级别的CFG,下面给你分享几种实用的方式:

1. 用LLVM的llc工具直接查看或导出机器码CFG

这是最快捷的方式,不需要写额外代码:

  • 可视化展示:使用-view-machine-cfg选项,LLVM会自动弹出图形窗口展示机器码CFG。步骤如下:
    1. 先把你的高级语言源码编译成LLVM IR:
      clang -O0 -S -emit-llvm your_source.c -o your_source.ll
      
    2. 用llc处理IR并触发CFG可视化:
      llc -view-machine-cfg your_source.ll
      
      这个选项依赖Graphviz,如果没安装的话需要先装一下(比如Ubuntu上apt install graphviz)。
  • 文本形式导出:如果不需要可视化,用-print-machine-cfg选项可以把CFG输出到终端或文件:
    llc -print-machine-cfg your_source.ll > machine_cfg.txt
    
    输出内容会包含每个机器基本块(Machine Basic Block)的编号、指令,以及块之间的跳转关系。

2. 通过LLVM后端API程序化获取CFG

如果你需要在代码里处理机器码CFG,可以写一个LLVM Machine Function Pass来遍历和提取信息:

  • LLVM的MachineFunction类对应一个函数的机器码表示,里面包含多个MachineBasicBlock(MBB)实例,每个MBB就是CFG的一个节点。
  • 每个MBB提供predecessors()和successors()方法,可以直接获取它的前驱和后继块,从而构建完整的CFG结构。
  • 简单的实现思路:继承MachineFunctionPass,在runOnMachineFunction方法里遍历所有MBB,逐个收集它们的邻接关系,然后输出或存储为你需要的格式。

3. 查看Machine IR(MIR)阶段的CFG

LLVM后端会先生成基于SSA的机器IR(也就是你提到的“基于SSA的机器码”),这个阶段的CFG和最终机器码的CFG结构几乎一致,只是指令还没经过寄存器分配等最终优化。你可以用llc输出MIR来查看:

llc -stop-after=machine-scheduler -o - your_source.ll

输出的MIR中会清晰标注每个MBB的跳转指令和块之间的依赖关系,也能帮你理解机器码CFG的生成过程。

补充说明

如果你已经有了编译好的目标文件,也可以用llvm-objdump反汇编后,通过分析跳转指令(比如x86的jmp、je等)手动或用脚本构建CFG,但这种方式不如直接用LLVM后端工具/API准确,因为反汇编会丢失LLVM内部的一些块标记信息。

内容的提问来源于stack exchange,提问作者soham

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 04:10:51