鏈接
鏈接是將各種代碼和數據片段收集並組合爲一個單一文件的過程。
這個文件可以被加載到內存並執行。
鏈接可以執行於編譯時,也可以執行於加載時,甚至執行於運行時。在早期的計算機系統中,鏈接是手動執行的。
在現代系統中,鏈接是由叫做鏈接器的程序自動執行的。
靜態鏈接
像linuxLD程序這樣的靜態鏈接器,以一組可重定位目標文件和命令行參數作爲輸入,生成一個完全鏈接的,可以加載和運行的可執行目標文件作爲輸出.
輸出的可重定位目標文件由各種不同的代碼和數據節組成,每一節都是一個連續的字節序列,指令在一節中,初始化了的全局變量在另一節中,而未初始化的全局變量又在另外一節中。
爲了構造可執行文件,鏈接器必須完成兩個主要任務:
符號解析:
目標文件定義和引用符號。每個符號對應於一個函數,一個全局變量或一個靜態變量。
符號解析的目的是將每個符號引用正好和一個符號定義關聯起來。
重定位:
編譯器和彙編器生成動地址0開始的代碼和數據節。鏈接器通過把每個符號定義與一個內存位置關聯起來。從而重定位這些節。然後修改所有對這些符號的引用,使它們指向這個內存位置。鏈接器使用彙編器產生的重定位條目的詳細指令,不加甄別地執行這樣的重定位。
目標文件:
目標文件:純粹是字節塊的集合。這些塊中,有些包含程序代碼,有些包含程序數據代碼,而其它的則包含引導鏈接器和加載器的數據結構,鏈接器將這些塊連接起來,確定被連接塊運行的位置,並且修改代碼和數據塊中的各種位置。
目標文件有三種形式:
可重定位的目標文件:包含二進制代碼和數據,其形式可以在編譯時與其它可重定位的目標文件合併起來,創建一個可執行目標文件。
可執行目標文件:包含二進制代碼和數據。其形式可以被直接複製到內存並執行。
共享目標文件:一種特殊類型的可重定位目標文件,可以在加載或者運行時被動態加載進內存並鏈接。
目標文件是按照特定的目標文件格式來組織的,各個系統的目標文件格式都不相同,Mac OS-X使用Mach-O格式。