接下來,即將啟動 ELF 格式的「execution view」介紹。本日記是進入「dynamic loader」前的準備工作「之一」。
果然是很大挑戰的研究。說明幾個注意事項如下。
必須了解 ELF 的格式觀念
「Executable and Linking Format」專欄已經把 ELF 格式的「linking view」做了初步的介紹,在此專欄裡,Jollen 針對 ELF 格式的概念以 loader v0.1~v0.5 共五個範例做說明。想要了解 ELF 格式的朋友,可以參考此專欄。
Section 的用途摘要說明
每個 section 都有不同的用途,在 SysV ABI 裡所定義的特殊 section 與其用途整理如下:
Section | 用途 |
.bss | 用來置放程式裡未初始化的資料(uninitialized data),當程式執行時預設會將這裡的資料初始化為0(zero)。 |
.comment | 置放版本控制資訊。 |
.data | 置放已初始化的資料(initialized data) |
.data1 | 置放已初始化的資料(initialized data) |
.debug | 置放除錯時所使用資訊。 |
.dynamic | 置放dynamic linking(動態連結)使用資訊。 |
.dynstr | 置放dynamic linking所需的字串。 |
.dynsym | 置放dynamic linking symbol table(動態連結符號表) |
.fini | 當程式正常結束後,系統會執行此section裡的程式碼。 |
.got | Global Offset Table |
.hash | Symbol Hash Table |
.init | 當程式開始執行時,系統會在進入程式進入點前(C的main() 函數)執行此section裡的程式碼。 |
.interp | 置放program interpreter(程式直譯器)的path name(路徑名稱)。 |
.line | 置放編譯後的機器碼與原始程式之間的對應資訊,利用gdb 的list命令可以列出object file的原始程式碼,就是參考此 section的資訊。 |
.note | 紀錄用section。 |
.plt | Procedure Linkage Table |
.relname | 置放relocation資訊。 |
.relaname | 置放relocation資訊。 |
.rodata | 置放read-only(唯讀)資料。 |
.rodata1 | 置放read-only(唯讀)資料。 |
.shstrtab | Section Name String Table。置放section的名稱字串。請參考本章範例程式的說明。 |
.strtab | Symbol table的string table。 |
.symtab | Symbol Table |
.text | 置放“text”資料,即可執行的程式指令。 |
前陣子「jserv」兄的深入淺出 Hello World的演講把 ELF 格式「執行時期」的作業系統行為做了很不錯的「整體概念」呈現,對於執行時期 ELF object file 的概念呈現,jserv 兄的簡報會比我接下來要分享的專欄更為細膩而且連貫。
整體觀念:jserv 兄的「深入淺出 Hello World Part I/II」
很精采的 ELF 執行時期系統行為的分享。
雖然準備 ELF 與 loader 的專欄花了不少時間,但是還是覺得寫的不好。原因是,對於這種必須深入系統內部細節的技術討論,「整體概念」的一次呈現是相當重要的。對於 ELF 執行時期系統行為的討論,我要推薦 jserv 兄的「深入淺出 Hello World」系列演講;對於整體的概念呈現,jserv 的簡報做的比我的專欄還要好。
知識若能分享,就不必重造車輪,開放源碼分享的是知識,而不是程式碼。Jollen 自己的「ELF 執行時間」專欄,整體的呈現方式一直拿不定主意,還好,直接以 jserv 兄分享的簡報做為藍本,就容易多了!
需要了解 Linux 的 Memory Management 嗎?
需要懂一點概念,但不用深入 kernel code。
Linux 的 memory management 並不是容易撰寫的題目,這道題目的規劃走向可以是「kernel code 導向」,也可以是「概念式導向」,前者以 kernel code 來說明,後者以圖解觀念的方式進行;前者的優點是具體而且可以很細微,但是考驗作者的功力,後者的優點是概念能清楚呈現,但細膩度不足。
我認為,一開始選擇「概念式導向」的呈現方式會比較適當,這應該也是大家比較可以接受的方式。
.bss 節區
這是一個很特殊的節區,「linking view」上,他不佔檔案空間、他用來存放「未初始化的變數」。Process(程式執行時)會具備這個特殊的節區。因此,我們只討論 .bss section 的「process virtual address」,而不討論「.bss section 所在的 file offset」。
之後再寫日記,以一段 code 來說明。
注記
Jollen's Blog 使用 Github issues 與讀者交流討論。請點擊上方的文章專屬 issue,或 open a new issue
您可透過電子郵件 jollen@jollen.org,或是 Linkedin 與我連絡。更歡迎使用微信,請搜尋 WeChat ID:jollentw