《深入理解計算機系統》——第7章(連結)
連結
連結:將各種程式碼和資料部分收集起來並組合成為一個單一檔案的過程。(這個檔案可被載入或拷貝到儲存器並執行)
連結可以執行於編譯,載入或執行時。
靜態連結:
兩個主要任務:
1 符號解析:將目標檔案中的每個全域性符號都繫結到一個唯一的定義
2 重定位:確定每個符號的最終儲存器地址,並修改對那些目標的引用
符號表:
typedef struct{ int name; //字串表中的位元組偏移,指向符號的以NULL結尾的名字
int value; //符號的地址,對於可重定位的模組是距定義目標的節起始位置的偏移。
int size; //目標大小(單位:位元組)
char type:4 , //資料或函式
binding:4; //本地LOCAL/全域性GLOBAL
char reserved;
char section; //到節頭部表的索引
}Elf_Symbol;
每個符號都和目標的某個節相關聯,由section欄位表示。
section欄位三個特殊的偽節
ABS:不該被重定位的符號。
UNDEF:未定義的符號,在本目標模組中引用,但在其他地方定義。
COMMON:未被分配位置的未初始化資料目標。
Ndx=1表示.test節,Ndx=3表示.data節。
目標檔案三種形式:
1可重定位目標檔案
2可執行目標檔案
3共享目標檔案
共享目標檔案(共享庫)是在執行時由動態連結器連結和載入,或者隱含地在呼叫程式被載入和開始執行時,或者根據需要在程式呼叫dlopen庫的函式。
載入器將可執行檔案的內容對映到儲存器,然後呼叫動態連結器,通過載入共享庫和重定位程式中的引用來完成連結任務。
Fpic
被編譯為位置無關程式碼的共享庫可以載入到任何地方,也可以在執行時被多個程序共享
編譯庫程式碼,使得不需要連結器修改庫程式碼就可以在任何地址載入和執行這些程式碼。
使用者對GCC使用-fPIC選項指示GNU生成PIC程式碼
處理目標檔案的工具
AR:建立靜態庫,插入、刪除、列出和提取成員。
STRINGS:列出一個目標檔案中所有可列印的字串。
STRIP:從目標檔案中刪除符號的資訊。
NM:列出一個目標檔案的符號表中定義的符號。
SIZE:目標檔案中節的名字和大小。
READELF:顯示一個目標檔案的完整結構,包括ELF頭中的編碼的所有資訊。包含SIZE和NM的功能。
OBJDUMP:所有二進位制工具之母,能夠顯示一個目標檔案中所有的資訊。它最大的作用是反彙編.text節中的二進位制指令。
LDD:列出一個可執行檔案在執行時所需要的共享庫。