一.文件解析(鏈接)過程
- 彙編器將彙編文件xxx.s編譯成可重定位目標文件
- 目標文件由若干個Section組成,咱們在彙編程序中聲明的.section會成爲目標文件中的Section,此外匯編器還會自動添加一些Section(好比符號表)。
- 鏈接器將多個可重定位文件翻譯成可執行目標文件
- 把目標文件中的Section(節)合併成幾個Segment(段)。
TIPS: 例如將swap.o 和main.o 翻譯成可執行文件P: ld -o P swap.o main.o編程
二.目標文件
- 在編譯過程當中有多種文件,彙編和鏈接部分有三種文件(ELF文件)
-
- 可重定位目標文件: 包涵二進制代碼和數據。其做用:在編譯時與其它可重定位目標文件合併起來,建立一個可執行目標文件。
- 和可執行文件區別:自包含當前文件的符號解析,而且符號都沒有實際的虛擬地址
-
- 可執行文件: 包含二進制代碼和數據。做用:可用被直接拷貝到存儲器並執行.
-
- 共享目標文件: 一種特殊類型的可重定位目標文件。做用:加載或者運行時唄動態地加載到存儲器並連接。
-
三.彙編器
- 這個文件是彙編器編譯單個文件生成的(xxx.o)文件,可重定位目標文件(ELF格式).下面是各section
- .text: 已編譯程序的機器代碼
- .rodata: 只讀數據,好比printf語句中的格式串和開關語句的跳轉表
- .data: 已初始化的全局C變量。局部變保存在棧中.
存放具體數據
- .bss: 未初始化的全局C變量,不佔空間,僅僅是一個佔位符。目標文件格式區分初始化和未初始uabianl是爲了空間效率。
- .symtab: 一個符號表。存放在程序全部符號 (
函數/變量
) 的符號名、section號、地址、約束。約束信息:global、local這種限定
- .rel.text: 鏈接時.text 中須要修改地址的函數。
- .rel.data:鏈接時.data 中須要修改地址的變量。
- debug: 一個調試符號表
- line: 原始C源程序中的行號和.text節中機器指令之間的映射。
- .strtab: 一個字符串表
四.連接器
-
1.連接的做用的過程函數
- 編譯時:將源代碼翻譯成機器代碼
- 加載時: 程序被夾在器加載到存儲器並執行
- 運行時:由程序執行
-
2.特色翻譯
- 理解連接將幫助你構造大型程序。
- 理解鏈接將幫助你避免一些危險的編譯錯誤
- 理解鏈接將幫助你理解語言的做用域規則是如何實現的。
- 理解鏈接將幫助你理解語其它重要的系統概念
- 理解鏈接將使你可以利用共享庫
-
3.編譯時的做用debug
- 符號解析: 彙編器生成的是從地址0開始的代碼和數據節,鏈接器將每一個符號引用恰好和一個符號定義聯繫起來。將多個文件的全局變量和函數(默認全局)、static靜態變量和static函數與
引用
,關聯起來。若是有重複,則經過規則肯定引用的惟一性 - 重定位:
- 彙編器:生成的是從地址0開始的代碼和數據節。
- 鏈接器:把每一個符號與一個存儲器位置聯繫起來,而後修改全部對這些符號的引用,使它們指向這個存儲器的位置,從而重定位這些字節。
- 就是給全局變量和函數(默認全局)、static靜態變量和static函數分配地址
- 符號解析: 彙編器生成的是從地址0開始的代碼和數據節,鏈接器將每一個符號引用恰好和一個符號定義聯繫起來。將多個文件的全局變量和函數(默認全局)、static靜態變量和static函數與
-
4.符號和符號表調試
- 由模塊m (文件m) 定義能被其它模塊引用的全局符號
- 有其它模塊定義能被模塊m (文件m) 引用的全局符號
- 只被模塊m (文件m) 定義和引用的本地符號:static 變量(全局/本地)和函數
-
5.符號解析規則code
- 將每一個引用與它的定義文件(可重定位目標文件)的符號表中的一個肯定的符號聯繫起來。
- 就是將引用符號替換成定義的虛擬地址空間中的地址(該地址記錄在定義文件的符號表中)
- 將每一個引用與它的定義文件(可重定位目標文件)的符號表中的一個肯定的符號聯繫起來。
-
6.解析全局符號規則ip
- 不容許多個強符號。直接被初始化值的全局變量,不能同名定義多個
- 若是有一個強符號和多個弱符號,那麼選強符號
- 若是有多個弱符號,那麼從這些弱符號中任選一個
- tips:強符號:被初始化的值的全局變量或函數;弱符號
-
7.與靜態庫鏈接內存
- gcc main.c /usr/lib/libm.a /usr/lib/libc.a
-
8.解析靜態庫的引用作用域
- 三個集合:
- 1 可重定位目標文件E,會被合併形參可執行文件
- 2 引用了,可是還沒有定義的符號集合U
- 3 前面輸入文件已經定義的符號D
- 規則
- 先掃描符號到U
- 將定義了的符號(可能現階段纔剛剛掃描一部分)存放到D,未定義的存放到E
- 最後合併E中的目標文件,從而構建輸出的可執行文件.
- 三個集合:
-
9.可重定位字符串
-
一旦鏈接器完成了符號解析這一步,它就把每一個符號引用和肯定的一個符號定義聯繫起來了
-
重定位節和符號定義:鏈接器將全部相同類型的節合併爲同一類型的新的聚合節(段),並運行時的存儲器地址賦給新的聚合節(段)。
虛擬內存是以頁爲單位加載的,同一頁必須相同的讀寫修改權限,一段能夠多個頁
-
重定位節中的符號引用:鏈接器修改代碼節和數據節中對每一個符號的引用,將他們指向正確的運行時地址。
生成可執行目標文件
-
-
10.可執行目標文件
ELF的格式的可執行目標文件,帶有地址的聚合文件,可加載到系統中