可執(zhí)行文件中的代碼段和數(shù)據(jù)段由目標(biāo)文件合并而來拐格,如何合并的呢?
1. 兩步鏈接(Two-pass Linking)
采用相似段合并的方法刑赶,整個(gè)過程分兩步捏浊。
1.1 空間與地址分配
掃描所有的輸入目標(biāo)文件,獲取它們的各個(gè)段的長度撞叨、屬性和位置金踪,將相似的段合并,計(jì)算出合并后的長度與位置牵敷,并建立映射關(guān)系胡岔。將文件中的符號表的所有符號收集起來,統(tǒng)一放到一個(gè)全局符號表枷餐。
1.2 符號解析和重定位
使用上面步驟中得到的信息靶瘸,讀取段的數(shù)據(jù)、重定位信息毛肋,進(jìn)行符號解析(將引用符號與定義符號建立關(guān)聯(lián))與重定位怨咪。
2. 強(qiáng)符號和弱符號
對C++來說,編譯器默認(rèn)函數(shù)和初始化了的全局變量為強(qiáng)符號润匙,未初始化的全局變量為弱符號诗眨,是針對定義來說的。
2.1 多次定義的全局符號規(guī)則
- 強(qiáng)符號不允許被多次定義(即不同文件中不能有同名的強(qiáng)符號)孕讳。
- 符號在某個(gè)文件中是強(qiáng)符號匠楚,在其他文件中是弱符號,則該符號是強(qiáng)符號厂财。
- 符號在所有文件中都是弱符號油啤,則選占用空間最大的一個(gè)。
2.2 C++為什么允許不同類型的弱符號存在
鏈接器不支持符號類型蟀苛,即鏈接器無法判斷符號的類型是否一致益咬。