C鏈接2 -目標(biāo)文件

鏈接器的任務(wù)

在上一篇文章中,我們提到鏈接是將多個(gè)可重定位目標(biāo)文件鏈接成一個(gè)可執(zhí)行目標(biāo)文件。必須要完成2件事

  • 符號解析,將每一個(gè)符號引用的定義聯(lián)系起來,比如foo.c中的num定義的地方是在main.c中。
  • 重定位,編譯器和匯編器生成從0地址開始的代碼和數(shù)據(jù)節(jié)(下文會提到),鏈接器把每一個(gè)符號定義與存儲器位置聯(lián)系起來,然后修改所有對這些符號的引用。使得它們有正確的存儲器地址。從而重定位這些節(jié)。
目標(biāo)文件

目標(biāo)文件一共有3類:

  • 可重定位目標(biāo)文件,包含二進(jìn)制代碼和數(shù)據(jù),可以在;鏈接器中和其他可重定位目標(biāo)文件合并為1個(gè)可執(zhí)行目標(biāo)文件。
  • 可執(zhí)行目標(biāo)文件,包行二進(jìn)制代碼和數(shù)據(jù)。
  • 共享目標(biāo)文件,一種特殊類型的可重定位目標(biāo)文件,可以在加載或者運(yùn)行時(shí)被動態(tài)的加載到存儲器并鏈接。
可重定位目標(biāo)文件

||
|---------|-----------|
|ELF頭|包括目標(biāo)ELF頭的大小,目標(biāo)文件的類型,機(jī)器類型,節(jié)頭部表等信息主要用來幫助鏈接器語法分析個(gè)解釋目標(biāo)文件的信息。
|.text|已編譯程序的機(jī)器代碼|
|.rodata|只讀數(shù)據(jù),比如"hello world"字符串和開關(guān)語句跳轉(zhuǎn)表
|.data|已初始化的全局C變量
|.bss|未初始化的全局C變量
|.symtab|符號表,存放程序定義和引用的函數(shù)和全局變量的消息。有別于編譯器的符號表
|......|......|

符號和符號表

每個(gè)可重定位目標(biāo)模塊m都有一個(gè)符號表,它包含m所定義和引用的符號信息。

  • 由m定義并能被其他模塊所引用的全局符號,對應(yīng)于非靜態(tài)的static屬性的C函數(shù)和一級定義為不帶static屬性的全局變量。
  • 由其他模塊定義并被模塊m引用的全局符號。這些符號稱為外部符號(external)對應(yīng)于定義在其他模塊中的C函數(shù)和全局變量
  • 只被模塊m定義和引用的本地符號,有的本地鏈接器符號對應(yīng)于帶static屬性的C函數(shù)和全局變量。

可重定位目標(biāo)文件中有匯編器定義的符號表。

// ELF符號表?xiàng)l目
typedef struct{
    int name;            // 
    int value;            // 符號地址,可重定位來說是節(jié)起始位置的偏移,對于可執(zhí)行來說是絕對運(yùn)行的地址。
    int size;              // 目標(biāo)的大小
    char type: 4       // 通常是數(shù)據(jù)或者函數(shù)
    char binding: 4  // 本地符號還是全局符號
    char section      // 每個(gè)符號都和目標(biāo)文件的某個(gè)節(jié)相關(guān)聯(lián),這個(gè)字段表示某個(gè)節(jié),該字段是到節(jié)頭部表的索引。   
    ......         
}ELF_Symbol

關(guān)于節(jié)頭部表參考網(wǎng)友ELF文件-節(jié)和節(jié)頭

符號解析

鏈接器解析符號引用的方法是將每一個(gè)引用與它輸入的可重定位目標(biāo)文件的符號表中的一個(gè)確定的符號定義聯(lián)系起來在這里會有個(gè)問題,比如在C++/Java中函數(shù)可以重載,那么它們函數(shù)名的符號表不是沖突了嗎?
在這里,編譯器采用了一種叫做name mangling(中文有多種翻譯,但都感覺怪怪的,這里不翻譯了)的做法。其實(shí)質(zhì)就是將每個(gè)方法和參數(shù)列表組合編碼成對鏈接器來說唯一的名字。比如Foo::bar(int, long)被編碼為bar__Fooil.這也從另一個(gè)角度說明了為什么函數(shù)重載區(qū)分度為不同的參數(shù)類型和個(gè)數(shù)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容