LLVM IR概述
- 優化是對LLVM IR進行操作:
什麼是LLVM IR
- LLVM IR 是一門低級語言,語法類似於彙編
- 任何高級編程語言(如C++)都可以用LLVM IR表示
- 基於LLVM IR可以很方便地進行代碼優化
LLVM IR的兩種表示方法
- 第一種是人類可以閱讀的文本形式,文件後綴爲.ll
- 第二種是易於機器處理的二進制格式,文件後綴爲.bc
LLVM IR結構
- 源代碼被編譯爲LLVM IR後,具有以下結構:
LLVM IR結構:模塊 Module
- 一個源代碼對應LLVM IR中的一個模塊。
- 頭部信息包含程序的目標平臺,如X86、ARM等,和一些其他信息。
- 全局符號包含全局變量、函數的定義與聲明。
LLVM IR結構:函數 Function
- LLVM IR中的函數表示源代碼中的某個函數。
- 參數,顧名思義爲函數的參數。
- 一個函數由若干基本塊組成,其中函數最先執行的基本塊爲入口塊。
LLVM IR結構:基本塊 BasicBlock
- 一個基本塊由若干個指令和標籤組成。
- 正常情況下,基本塊的最後一條指令爲跳轉指令(br或者switch),或返回指令(retn),也叫作終結指令(Terminator Instruction)。
- PHI指令是一種特殊的指令。
LLVM IR結構
- 瞭解LLVM IR的結構是我們學習代碼混淆的基礎,舉個例子
- 以函數爲基本單位的混淆:控制流平坦化
- 以基本塊爲基本單位的混淆:虛假控制流
- 以指令爲基本單位的混淆:指令替代
LLVM IR常用指令講解
-
終結指令 Terminator Instructions
- ret指令
- 函數返回指令,對應C/C++中的return。
- br指令
- br是“分支”的英文branch的縮寫,分爲非條件分支和條件分支,對應C/C++的if語句
- 無條件分支類似有x86彙編中的jmp指令,條件分支類似於x86彙編中的jnz,je等條件跳轉指令。
- ret指令
-
比較指令
- icmp指令
- 整數或指針的比較指令
- 條件cond可以是eq(相等),ne(不相等),ugt(無符號相等)
- fcmp指令
- 浮點數的比較指令
- 條件cond可以是oeq(ordered and equal),ueq(unordered or equal)
- switch指令
- 分支指令,可看做是br指令的升級版,支持的分支更多,但使用也更復雜,對應C/C++中的switch。
- icmp指令
-
二元運算 Binary Operations
- add指令
- sub指令
- mul指令
- udiv指令
- 無符號整數除法指令
- sdiv指令
- 有符號整數除法指令
- urem指令
- 無符號整數取餘指令
- srem指令
- 有符號整數取餘指令
-
按位二元運算 Bitwise Binary Operations
- shl指令
- 整數左移操作指令
- lshr指令
- 整數右移指令
- ashr指令
- 整數算數右移指令
- and指令
- 整數按位與運算指令
- or指令
- 整數按位或運算指令
- xor指令
- 整數按位異或運算指令
- shl指令
-
內存訪問和尋址操作 Memory Access and Addressing Operations
- alloca指令
- 內存分配指令,在棧中分配一塊空間並獲得指向該空間的指針,類似與C/C++中的malloc函數
- store指令
- 內存存儲指令,向指針指向的內存中存儲數據,類似與C/C++中的指針引用後的賦值操作
- alloca指令
-
類型轉換操作 Conversion Operations
- trunc..to指令
- 截斷指令,將一種類型的變量截斷爲另一種類型的變量。
- zext..to指令
- 零擴展指令,將一種類型的變量拓展爲另一種類型的變量,高位補0。
- sext..to指令
- 符號位拓展指令,通過複製符號位(最高位)將一種類型的變量拓展爲另一種類型的變量。
- trunc..to指令
-
其他操作 Other Operations
-
phi指令:由靜態單賦值引起的問題
-
select指令
- ? : 三元運算符
-
call指令
- call指令用來調用某個函數,對應C/C++中的函數調用,與x86彙編中的call指令類似。
-