ELF Format 筆記(五)—— 特殊 Section,elfsection
連結器把一些獨立的 object files 和庫檔案連結起來,形成可執行檔。在這個過程中,連結器需要解決一些符號的引用以及指令的重定位。
除此之外,還有一個動態連結的過程。比如有些符號是定義在某個 so 檔案中的,需要由動態連結器在裝載的過程中進行一些符號尋找和地址重定位的工作。要完成此工作,動態連結器需要一些資訊,它們儲存在一些特殊的 section 中,比如 .dynamic。
section 和 segment 是分別針對連結視圖和執行視圖來說的,各種資料對他們的翻譯比較混亂,慢慢就會理解了。
還有一些用於支援調試功能的 section,比如 .debug、.line。下面是一張描述特殊 section 的表格:
.bss:儲存未初始化的資料,比如那些未初始化的全域變數。因為是“未初始化”,所以也沒必要在檔案中佔用任何空間去記錄其初始值(所以類型為 SHT_NOBITS)。在程式開始運行時,系統會將 .bss 映射的記憶體地區清零。
.comment:儲存版本控制資訊。
.data / .data1:儲存已初始化的資料。它們會在檔案中佔用儲存空間,這與 .bss 不同。
.debug:儲存調試相關的資訊。
.dynamic:儲存動態連結資訊。
.dynstr:儲存動態連結所需的字串。比如符號表中的每個符號都有一個 st_name(符號名),他是指向字串表的索引,這個字串表可能就儲存在 .dynstr。
.dynsym:儲存需要動態串連的符號表。
.fini / .init:分別儲存進程退出和初始化時要執行的指令。.init 指令會在程式進入點(main)之前被執行。
.got:儲存全域位移量表 (global offset table)。
在 Android 中,GOT 分為兩部分:.got 和 .got.plt。其中 .got 表用來儲存全域變數引用的地址,而 .got.plt 用來儲存函數引用的地址。
.hash:儲存符號雜湊表,用於快速尋找與其對應的符號表中的符號。
.interp:儲存 ELF 程式解譯器(比如 Android 下的動態連結器)的路徑名。
.line:儲存用於調試的行號資訊。
.note:儲存一些注釋資訊。
.plt:儲存過程連結資料表 (procedure linkage table)。每個外部定義的函數都會在 PLT 中有對應的一項,用於定位外部函數的地址。
.relname / .relaname:儲存重定位表。比如:.rel.dyn、.rel.plt。
.rodata / .rodata1:儲存程式中的唯讀資料。
.shstrtab:儲存一個字串表,這些字串都是 section 的名字。
.strtab:儲存字串表,類似於 .dynstr,但 .dynstr 中儲存的都是那些需要動態連結的符號的名字。
.symtab:儲存符號表(非動態連結)。
.text:儲存可執行檔指令代碼。
這些以“.”為首碼的 section 名字為系統保留。應用程式可以構造自己的段,但最好不要與系統已定義 section 節重名,也不要以“.”開頭,以避免潛在的衝突。