? ? ?鏈接過程實質上就是把不同目標文件粘在一起,對不同目標文件中定義或引用的相同名字進行決議resolve和綁定binding。
一、符號的分類
?????1、定義在本目標文件中的全局符號,可以被其它文件引用。
?????2、在本目標文件中引用的全局符號,卻沒有定義在本目標文件,這一般叫做外部符號(External Symbol), 也就是我們前所謂符號引用。
? ? ?3、段名,這種符號通常由編譯器產生,它的值就是該段的起始地址。
? ? ?4、局部符號,這類符號只在當前編譯單元內部可見。局部符號對于鏈接過程沒有作用,鏈接器往往忽略它們。 ? ?
? ? ?5、行號信息,即目標指令與源代碼中代碼行的對應關系,它是可選的。
?????鏈接關心的是各種全局符號。
二、弱符號與強符號
在C語言中,函數和初始化的全局變量(包括顯式初始化為0)時強符號;未初始化的全局變量時弱符號。
注意:強符號和弱符號是針對定義來說的,不是針對引用來說的。

例如:weak_num、weak_num2是弱符號;strong_num和fun事強符號;ext即非強符號也非弱符號,因為他是一個外部變量的引用。
1、強符號
在鏈接時經常會碰到重復定義。多個目標文件中含有名字相同全局符號的定義,那么這些目標文件在鏈接的時候將會出現(xiàn)符號重復定義的錯誤。此類符號被稱之為強符號: 對C語言來說,編譯器默認函數和初始化了的全局變量為強符號。
不同的目標文件中不能有同名的強符號,否則不能鏈接在一起。
2、弱符號
?? ?? ? 未初始化的全局變量為弱符號。
?? ?? ? 也可以通過GCC的 __attribute ((weak)) 來定義一個強符號為弱符號。
聲明一個符號fun,屬性為weak,但并不定義它,這樣鏈接器將此為定義的weak symbol賦值為0。調用未符號的弱符號會core dump。
3、查看一個目標文件中符號類型
nm ***.o
4、強符號、弱符號使用規(guī)則
1)同名的強符號只能有一個,否則編譯器會報重復定義。
2)允許一個強符號和多個弱符號,但定義會選擇強符號
3)當有多個弱符號時,編譯器會選擇占用空間最大的那個。