Is there a way to use LLVM and clang++ to generate a Control Flow Graph with x86 basic blocks?
I am able to generate control flow graphs using clang++ and LLVM’s opt, but the CFG’s basic blocks contain LLVM IR. Instead, I would like the basic blocks to contain x86 assembly.
Ideally this tool would be useful for visualizing optimization passes that a compiler makes to the code and ultimately the assembly.
I don't think there is a direct tool in llvm. But the default clang -S output
(-fverbose-asm) is actually not too bad. You can find labels for machine basic
Some reverse engineering tools (e.g. radare2) have pretty viewers.
It is possible to view the control-flow graphs of Machine IR in LLVM, which much more approximates machine code. However, there is no way that I am aware of to get a CFG containing machine IR displayed from the command line; you have to inject calls to MachineFunction::viewCFG manually (which requires a debug build).
As Fangrui points out, there are other reverse engineering tools that can turn an assembly function into a graphical view of basic blocks. All of the standard disassemblers (IDA, BinaryNinja, Radare2/cutter, Ghidra) should be capable of this task. Hooking up your own hacky script to build a graphical view given an assembly file or object file as input is not a challenging task (unless you want to support the variety of ways switch tables are emitted).