本文旨在記錄 Computer Systems: A Programmer's Perspective (CS:APP) 一書第七章閱讀心得,該書是 CMU 的計算機系統概論的教材 (難度相當於台灣的大學高年級),該書的簡體中文翻譯名稱為《深入理解計算機系統》。
CS:APP 亦是 Linux Kernel Internals 2024 Spring 課程指定教材,並一同收錄於
Linux Kernel Internals 2024 Spring Collections。
我們知道常說的 compiling 事實上是指 Compiler Driver 的一系列工作,即將 C 轉換成可執行檔的多個過程,包含
本章名 Linking 表示第三步是本章重點之一,然而,linking 也發生於執行期;前者是 static linking,也就是 linker 介入鏈結各項檔案時,後者則稱 dynamic linking,此時期最重要的工作之一就是指向動態分配的記憶體位置,以及載入 shared object files。
靜態連結期是編譯系統中的最後一個步驟,主要工作是將所有 text section 和 data section 分配到「好的位置」;首先我們知道,prog
是一連串 binary code,也就是 0000111100100...
,而 object files 則是由一連串 symbols、指令和 hex 組成的,故可以想像 linker 就是將 object files 的內容放到正確的位置以結合成執行檔,linker 的兩個主要任務稱為:
此處只要了解 object files 和執行檔的樣貌就能夠知道 static linking 的行為了,畢竟真正困難的工作, compiler 以及 assembler 已經完成,說到底 linker 僅僅是「重新擺放」 object files 罷了。
As you read, keep in mind some basic facts about linkers: Object files are merely collections of blocks of bytes. Some of these blocks contain program code, others contain program data, and others contain data structures that guide the linker and loader.
A linker concatenates blocks together, decides on run-time locations for the concatenated blocks, and modifies various locations within the code and data blocks.
分別更詳細的內容將於後面章節詳述。
Object files 事實上有三種型式
assembler 產生的是 relocatable object file,我們可以透過 objdump
readelf
hexdump
等方式查看其內容,如 objdump -d foo.o
而 linker 產生的執行檔 execute file 又可稱 executable object file,也就是一連串 binary code 組成的檔案。
而 shared object file 像是 .so
(有時稱 dynamic library file),會在執行期的 dynamic linking 時被放入執行檔中,好處是比起 static library file .a
可以節省檔案大小,但需要注意執行環境以及執行初期需要花費一些時間。
而發生在 static linking 的 .a
會在 7.6 中說明。
我們大致可以整理以下內容
.o
檔是 relocatable object file 由 assembler 產生
.so
是 shared object file,在執行期以 dynamic linking 的方式載入,使用如下
.a
檔稱作 static library file,在連結期以static linking的方式併入執行檔,使用如下
Executable and Linkable Format (ELF) 檔案被廣泛指涉 Linux 系統中具有固定結構的檔案,如 .text
.data
等,見下圖
被嚴格定義的原因是,它們用來和作業系統互動,如果是 executable ELF 則可直接被 OS loader 載入到記憶體並執行。
我們可以使用 readelf -h
展示 object files 的 ELF header,如 readelf -h *.o
使用在上述 object file 的執行檔之輸出為