理解 dynamic loader 內部原理的幾個先備知識(上):ELF 端的議題

jollen 發表於 December 14, 2006 11:39 PM

接下來,即將啟動 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 來說明。

注記

  • 2006.12.29: 調整標題。(Edited by Jollen)

Jollen's Blog 使用 Github issues 與讀者交流討論。請點擊上方的文章專屬 issue,或 open a new issue

您可透過電子郵件 jollen@jollen.org,或是 Linkedin 與我連絡。更歡迎使用微信,請搜尋 WeChat ID:jollentw