[英]What does ld do when linking against dynamic shared library?
在將應用程序與動態共享庫(例如in)鏈接時
gcc -o myprog myprog.o -lmylib
我知道鏈接器(在我的Linux上為ld
)使用-l選項在生成的myprog ELF可執行文件中存儲庫的名稱(在本例中為mylib
),該庫的名稱將在加載和鏈接時使用(在程序執行時如果我們忽略懶惰的動態鏈接,則可以開始)。 我想知道ld
的其他工作(關於編譯共享共享庫的靜態鏈接步驟)是關於動態共享庫的嗎?
ld
必須檢查提供的動態共享庫中是否存在未定義的符號 此外,我將對您使用的有關ELF格式以及動態鏈接和加載過程的指針(書籍,在線文檔)感興趣。
當您遇到鏈接到ELF共享庫時ld
需要做的最明顯的事情時,還有更多您錯過了。 我將重申您提到的內容並添加更多內容:
確保解析所有未定義的符號(除非輸出本身是共享庫,在這種情況下未定義的符號有效)。
在輸出文件的_DYNAMIC
對象的DT_NEEDED
記錄中存儲對該庫的引用。
如果輸出不是與位置無關的,並且在共享庫中引用了對象(就數據而言,相對於函數而言),則生成復制重定位以在加載時將對象的原始圖像復制到主程序的數據段中,以及正確的符號表條目,以便將對共享庫中對象的引用解析為主程序中的新副本,而不是庫中的原始副本。
為輸出中每個函數調用的目標生成PLT thunk,這些輸出在ld
-time尚未解析為輸出中的定義。
這些是我可以想到的特定於共享庫使用的任務,並且當然不包括鏈接器已經完成的所有工作,這些工作與靜態鏈接相同。 思考ld
對動態鏈接的作用的一種方法是,它使用具有大量重定位類型(表示編譯器或匯編器可以產生的任何內容)的目標文件,並解析除少數以外的所有文件(對於靜態鏈接而言,該數量將為零),其中所有剩余的重定位都適合於動態鏈接器在加載時可解析的類型更為有限的一組集合。
重要的一步是創建動態符號表 ,運行時鏈接程序ld.so
可以使用該符號表在運行時將可執行文件鏈接到庫。 它還將寫入動態重定位表,以指出需要更改哪些機器代碼位置以指向動態鏈接的符號。 要查看詳細信息:
objdump -T myprog
objdump -R myprog
還要注意,寫入可執行文件的字符串實際上是庫的SONAME
,可能類似於mylib.so.0
。 這將確保即使在以后安裝較新mylib.so.1.42
兼容的mylib.so.1.42
時,該可執行文件也將使用兼容的ABI版本0。 有關詳細信息:
ldd myprog
當然,鏈接器還會將您的目標文件相互鏈接,但是由於即使沒有動態共享庫,鏈接器也會這樣做,因此我認為您對此部分操作不感興趣。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.