2013-11-01 42 views
2

當鏈接到的動態共享庫的應用程序,如當鏈接到動態共享庫時,ld會做什麼?

gcc -o myprog myprog.o -lmylib 

我知道(在我的Linux ld)鏈接器使用-l選項中產生MYPROG ELF可執行文件存儲庫的名稱(在這種情況下爲mylib),它將用於加載和鏈接時(如果我們忽略惰性動態鏈接,程序將啓動時)。我想知道關於動態共享庫的ld(我只是在編譯時完成靜態鏈接步驟)執行的其他作業是什麼?

  • ld必須檢查未定義的符號存在於提供動態共享庫
  • 任何其他東西?

此外,我會對您正在使用的指針(書籍,在線文檔)感興趣,內容涉及ELF格式和動態鏈接和加載過程。

回答

3

雖然你在鏈接到ELF共享庫時最需要做的事情是ld,但還有一些你錯過了。我會重新狀態,你提到的那些更增添了一些:

  1. 確保所有未定義的符號都解決了(除非輸出是共享庫本身,在這種情況下未定義符號是有效的)。

  2. 存儲在輸出文件中的_DYNAMIC對象的DT_NEEDED記錄到庫的引用。

  3. 如果輸出不是位置無關的,並且在共享庫中引用對象(在數據意義上而不是函數上),則生成複製重定位以將對象的原始圖像複製到主程序的數據中加載時段的段以及正確的符號表條目,以便共享庫本身中對象的引用可以解析爲主程序中的新副本,而不是庫中的原始副本。

  4. 爲輸出中的每個函數調用的目的地生成PLT thunks,該輸出中未解析的輸出中的ld時間爲輸出中的定義。

這是我能想到的,是專門針對使用共享庫的任務,當然不包括鏈接已經沒有這將是一樣的靜態鏈接的所有工作。一種考慮ld對動態鏈接做什麼的方法是,它需要帶有大量重定位類型的目標文件(代表編譯器或彙編程序可以生成的任何東西),並解析除少數目標文件外的所有文件(對於靜態鏈接,將爲零),其中所有剩餘的重定位適合動態鏈接器在加載時可解析的更多有限類型的集合。

2

一個重要的步驟是創建一個動態符號表,運行時鏈接程序ld.so可用於在運行時將該可執行文件鏈接到庫。它還將編寫動態重定位表以注意哪些機器代碼位置需要更改爲指向動態鏈接的符號。要查看詳細信息:

objdump -T myprog 
objdump -R myprog 

還要注意的是寫入可執行文件的字符串實際上是圖書館的SONAME,這可能是這樣的mylib.so.0。這將確保即使您稍後安裝了較新且不兼容的mylib.so.1.42,可執行文件也會使用兼容的ABI版本0。有關詳情:

ldd myprog 

當然,鏈接器也將鏈接對象文件中對彼此,但因爲它即使在沒有動態共享庫的,我認爲你這個不感興趣部分操作。