連接是將各類代碼和數據部分收集起來並組合成爲一個單一文件的過程,這個文件可被加載(或拷貝)到存儲器並執行。
大多數編譯系統提供編譯驅動程序,它表明用戶在須要時調用語言預處理器、編譯器、彙編器和連接器。 連接能夠執行於編譯時,也就是在源代碼被翻譯成機器代碼時;也能夠執行於加載時,也就是在程序被加載器加載到存儲器並執行時;甚至執行於運行時,由應用程序來執行。
像Unix ld程序這樣的靜態連接器以一組可重定位目標文件和命令行參數做爲輸入,生成一個徹底連接的能夠加載和運行的可執行目標文件做爲輸出。輸入的可重定位目標文件由各類不一樣的代碼和數據節組成。指令在一個節中,初始化的全局變量在另外一個節中,而未初始化的變量又在另一個節中。
1.連接器有兩個主要任務:數據結構
符號解析: 目標文件定義和引用符號。符號解析的目的是將每一個符號引用恰好和一個符號定義聯繫起來。 重定位: 編譯器和彙編器生成從地址0開始的餓代碼和數據節。連接器經過把每一個符號定義與一個存儲器位置聯繫起來,而後修改全部對這些符號的引用,使得它們指向這個存儲器位置,從而重定位這些節。
2.連接器的屬性:目標文件純粹是字節塊的集合。命令行
這些塊中,有些包含程序代碼,有些則包含程序數據,而其餘的則包含指導連接器和加載器的數據結構。連接器將這些塊鏈接起來,肯定被鏈接塊的運行時位置,而且修改代碼和數據塊中的各類位置。連接器和彙編器已經完成了大部分工做。 目標文件純粹是字節快的集合。這些塊中,有些包含程序代碼,有些則包含程序數據,而其餘的則包括指導連接器和加載器的數據結構。連接器將這些塊連接起來,肯定被鏈接塊的運行時位置,而且修改代碼和數據塊中的各類位置。連接器對目標機器瞭解甚少。產生目標文件的編譯器和彙編器已經完成了大部分工做。
目標文件有三種形式:可重定位目標文件、可執行目標文件和共享目標文件。 編譯器和彙編器生成可重定位目標文件(包括共享目標文件)。連接器生成可執行目標文件。從技術上來講,一個目標模塊就是一個字節序列,而一個目標文件就是一個存放在磁盤文件中的目標模塊。 編譯器和彙編器生成可重定義目標文件(包括共享目標文件)。連接器生成可執行目標文件。 各個系統之間,目標文件格式都不相同。
ELF頭以一個16字節的序列開始,這個序列描述了生成該文件的系統的字的大小和字節順序。ELF頭剩下的部分包含幫助連接器語法分析和解釋目標文件的信息。其中包括ELF頭的大小、目標文件的類型(如可重定位、可執行或是共享的)、機器類型、節頭部表的文件偏移,以及節頭部表中的條目大小和數量。不一樣的節的位置和大小是由節頭部表描述的,其中目標文件中每一個節都有一個固定大小的條目。
在連接器的上下文中,有三種不一樣的符號: 由m定義並能被其餘模塊引用的全局符號 由其餘模塊定義並被模塊m引用的全局符號 只被模塊m引用的本地符號
重定位的組成: 重定位節和符號定義。 重定位節中的符號引用。
可執行目標文件的格式相似於可重定位目標文件的格式。ELF頭部描述文件的整體格式。 ELF可執行文件被設計得很容易加載到存儲器,可執行文件的連續的片被映射到連續的存儲器段。段頭部表描述了這種映射關係。
共享庫是致力於解決靜態庫缺陷的一個現代創新產物。 共享庫是一個目標模塊,在運行時,能夠加載到任意的存儲器地址,並加一個在存儲器中的程序連接起來。這個過程稱爲動態連接,是由一個叫作動態連接器的程序來執行的。共享庫也稱爲共享目標,在UNIX系統中一般用.so後綴來表示。