LLVM架构详述
文章目錄
- 什么是LLVM?
- 傳統(tǒng)編譯器架構(gòu)
- LLVM架構(gòu)
- 什么是Clang?
- 詞法分析
- 語(yǔ)法分析
- LLVM IR
- 源碼下載
什么是LLVM?
LLVM項(xiàng)目時(shí)模塊化,可重用的編譯器以及工具鏈技術(shù)的集合
美國(guó)計(jì)算機(jī)協(xié)會(huì)(ACM)將其2012年軟件系統(tǒng)獎(jiǎng)項(xiàng)頒給了LLVM,之前曾經(jīng)獲得此獎(jiǎng)的軟件和技術(shù)包括Java,Apache,Mosaic,the World Wide Web,Smalltalk,UNIX,Eclipse等等
創(chuàng)始人:
Chris Lattner,亦是Swift之父
有些文章把LLVM當(dāng)做Low Level virtual Machine(低級(jí)虛擬機(jī))的縮寫(xiě)簡(jiǎn)稱(chēng),官方描述如下:
The name “LLVM” itself is not an acronym;it is the full name of the project
“LLVM”這個(gè)名稱(chēng)本身不是首字母縮略詞,它是項(xiàng)目的全名
傳統(tǒng)編譯器架構(gòu)
Frontend:前端
詞法分析,語(yǔ)法分析,語(yǔ)義分析,生成中間代碼
Optimizer:優(yōu)化器
Backend:后端
生成機(jī)器碼
LLVM架構(gòu)
不同的前端后端使用同一的中間代碼LLVM Intermediate Representation(LLVM IR)
如果需要支持一種新的編程語(yǔ)言,那么只需要實(shí)現(xiàn)一個(gè)新的前端
如果需要支持一種新的硬件設(shè)備,那么只需要實(shí)現(xiàn)一個(gè)新的后端
優(yōu)化階段是一個(gè)通用的階段,它針對(duì)的是統(tǒng)一的LLVM IR,不論是支持新的編程語(yǔ)言,還是支持新的硬件設(shè)備,都不需要對(duì)優(yōu)化階段做修改
相比之下,GCC的前端和后端沒(méi)分得太開(kāi),前端后端耦合在一起,所以GCC為了支持一門(mén)新語(yǔ)言,或者為了支持一個(gè)新的目標(biāo)平臺(tái),就變得特別困難
LLVM現(xiàn)在被作為實(shí)現(xiàn)各種靜態(tài)和運(yùn)行時(shí)編譯語(yǔ)言的通用基礎(chǔ)結(jié)構(gòu) (GCC家族,Java,.NET,python,Ruby,Scheme,Haskell,D等)
什么是Clang?
LLVM項(xiàng)目的一個(gè)子項(xiàng)目
基于LLVM架構(gòu)的c/c++/Objective-C編譯器前端
官網(wǎng):http://clang.llvm.org/
相比于GCC,Clang具有如下優(yōu)點(diǎn)
廣義的LLVM
整個(gè)LLVM架構(gòu)
狹義的LLVM
LLVM后端(代碼優(yōu)化,目標(biāo)代碼生成等)
詞法分析
詞法分析,生成Token:
$ clang -fmodules -E -Xclang -dump -tokens main.m舉例
void test(int a ,int b){ int c=a+b-3; }
拆分成一個(gè)一個(gè)token,把每個(gè)東西一個(gè)一個(gè)地分割開(kāi),右邊13:9代表第13行第九個(gè)字符
語(yǔ)法分析
語(yǔ)法分析:生成語(yǔ)法樹(shù)(AST,Abstract SyntaxTree):
$ clang -fmodules -fsyntax -only -Xclang -ast-dump main.m舉例
void test(int a ,int b){ int c=a+b-3; }
LLVM IR
LLVM IR 有3種形式(但本質(zhì)是等價(jià)的,就好比水可以有氣體,液體,固體3種形態(tài))
1.text:便于閱讀的文本格式,類(lèi)似于匯編語(yǔ)言,拓展名.II
舉例:
void test(int a ,int b){ int c=a+b-3; }2.memory:內(nèi)存格式
3.bitcode:二進(jìn)制格式,拓展名.bc
IR基本語(yǔ)法:
注釋以分號(hào);開(kāi)頭
全局標(biāo)識(shí)符以@開(kāi)頭,局部標(biāo)識(shí)符以%開(kāi)頭
alloca:在當(dāng)前函數(shù)中棧幀中分配內(nèi)存
i32:32bit,4個(gè)字節(jié)的意思
align:內(nèi)存對(duì)齊
store:寫(xiě)入數(shù)據(jù)
load:讀取數(shù)據(jù)
官方語(yǔ)法參考:https://llvm.org/docs/LangRef.html
源碼下載
下載LLVM
$ git clone https://git.llvm.org/git/llvm.git/大小648.2M,僅供參考
下載clang
$ cd llvm/tools $ git clone https://git.llvm.org/git/clang.git/大小240.6M,僅供參考
源碼編譯
安裝cmake和ninja(先安裝brew,https://brew.sh/)
ninja如果安裝失敗,可以直接從github獲取release版放入[/user/local/bin]中
https://github.com/ninja-build/ninja/releases
在LLVM源碼同級(jí)目錄下新建一個(gè)[llvm_build]目錄(最終會(huì)在[llvm_build]目錄下生成[build.ninja])
$ cd llvm_build $ cmake -G Ninja ../llvm -DCMAKE_INSTALL_PREFIX=LLVM的安裝路徑舉例:
更多cmake相關(guān)選項(xiàng),可以參考:https://llvm.org/docs/CMake.html
依次執(zhí)行編譯,安裝指令
$ ninja編譯完畢后,llvm_build 目錄大概21.05G
$ ninja install安裝完畢后,安裝目錄大概11.92G
應(yīng)用與實(shí)踐:
官方參考:https://clang.llvm.org/docs/Tooling.html
應(yīng)用:語(yǔ)法樹(shù)分析,語(yǔ)言轉(zhuǎn)換等
Clang插件開(kāi)發(fā)
官方參考
https://clang.llvm.org/docs/ClangPlugins.html
https://clang.llvm.org/docs/ExternalClangExamples.html
https://clang.llvm.org/docs/RVAFrontendAction.html
應(yīng)用:代碼檢查(命名規(guī)范,代碼規(guī)范)等
Pass開(kāi)發(fā)(進(jìn)行中間代碼優(yōu)化)
官方參考:https://llvm.org/docs/WritingAnLLVMPass.html
應(yīng)用:代碼優(yōu)化,代碼混淆等
開(kāi)發(fā)新的編程語(yǔ)言
https://llvm-tutorial-cn.readthedocs.io/en/latest/index.html
https://kaleidoscope-llvm-tutorial-zh-cn.readthedocs.io/zh_CN/latest/
總結(jié)
- 上一篇: Windows_Reverse2逆向寒假
- 下一篇: VMprotect简介