LLVM中如何獲取程序的控制流圖CFG?

由於程序分析的需要,希望根據源碼獲取程序的CFG,但是llvm 的opt工具中的dot-cfg屬性得到的只是源碼對應彙編代碼的控制流圖的文本信息,類似與下圖的

圖形化表示是llvm所不能達到的嗎?如果可以的話,希望知友告知!!!


題主具體想做的是什麼?

如果是想寫代碼來遍歷和分析LLVM IR的CFG,那應該直接在LLVM IR的in-memory object model上操作;

如果是想做visualization,那dot文件不是很好么,題主只是貼出了dot渲染出來的圖片,但完全可以用原始的dot輸出啊。

原來題主是不知道怎麼把dot的文本渲染成圖片。

好辦啊,不想在自己機器上裝Graphviz的話就找在線的唄:

Erdos - Online Graphviz Viewer

題主在評論里說要渲染的圖是:

digraph "CFG for "main" function" {
label="CFG for "main" function";

Node0x32197b0 [shape=record,label="{entry:l %retval = alloca i32, align 4l %a = alloca i32, align 4l store i32 0, i32* %retvall store i32 0, i32* %a, align 4l %0 = load i32* %a, align 4l %cmp = icmp eq i32 %0, 0l br i1 %cmp, label %if.then, label %if.elsel|{&T|&F}}"];
Node0x32197b0:s0 -&> Node0x321a280;
Node0x32197b0:s1 -&> Node0x321a330;
Node0x321a280 [shape=record,label="{if.then: l %1 = load i32* %a, align 4l %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([7 x i8]*l... @.str, i32 0, i32 0), i32 %1)l br label %if.endl}"];
Node0x321a280 -&> Node0x321abd0;
Node0x321a330 [shape=record,label="{if.else: l %call1 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([6 x i8]*l... @.str1, i32 0, i32 0))l br label %if.endl}"];
Node0x321a330 -&> Node0x321abd0;
Node0x321abd0 [shape=record,label="{if.end: l ret i32 0l}"];
}

用在線渲染得到:


dot可以用graphviz打開啊。。


有很多cfg的pass,拿過來改改就ok.


推薦閱讀:

llvm memcpy的本質?
LLVM國內的開發者需要Social一下嗎?
怎麼將二進位代碼轉換為中間代碼(IR)呢?
如何理解LLVM的PassManager系統的實現?
為什麼很多語言的JIT實現最後會失敗,主要的技術原因和難點有哪些?

TAG:系統安全 | 編譯器 | LLVM | 程序分析 | Graphviz |