[英]When is dynamic linking between a program and a shared library performed?
在C語言中,何時在程序和共享庫之間執行動態鏈接:
一旦將程序加載到內存中,但是在執行程序的main()
之前,或者
執行完程序的main()
之后,何時執行對庫中例程的第一次調用? 當執行第二次或第三次或從庫中調用例程時,動態鏈接會再次發生嗎?
在開始閱讀以下引文之前,我一直在想第一個,現在不確定。
不確定操作系統是否重要,我使用的是Linux。
從操作系統概念:
通過動態鏈接,每個庫例程參考的映像中都包含一個存根。 存根是一小段代碼,指示如何找到合適的駐留內存的庫例程,或者如果該例程尚不存在,則如何加載該庫。
執行存根時 ,它將檢查所需的例程是否已在內存中。 如果不是,程序將例程加載到內存中。 無論哪種方式,存根都會用例程的地址替換自身並執行該例程。 因此, 下次到達特定代碼段時 ,將直接執行庫例程,而不會產生動態鏈接的開銷。 在這種方案下,所有使用語言庫的進程僅執行庫代碼的一個副本。
在開始閱讀以下引文之前,我一直在想第一個,現在不確定。
它很復雜(取決於您所謂的“動態鏈接”)。
Linux內核將a.out
加載到內存中。 然后,它檢查PT_INTERP
段(如果有)。
如果該段不存在,則二進制文件是靜態鏈接的,內核將控制權轉移到Elf{32,64}Ehdr.e_entry
(通常是_start
例程)。
如果PT_INTERP
段出現,內核加載到內存中,並將控制權轉移到它的 .e_entry
。 動態鏈接就是在這里開始的 。
動態加載程序重新定位自身,然后查找在a.out
小號PT_DYNAMIC
段上還有什么是必要的說明。
例如,它通常會發現一個或多個DT_NEEDED
項-共享庫a.out
直接對鏈接。 加載器加載任何這樣的庫, 它們初始化,並解決它們之間的任何數據的引用。
如果a.out
的PT_DYNAMIC
具有DT_FLAGS
條目,並且如果該條目包含DF_BIND_NOW
標志,則來自a.out
函數引用也將被解析。 否則(並假設環境中未設置LD_BIND_NOW
),將執行惰性PLT
解析(將函數解析為對任何給定函數的首次調用的一部分)。 詳細信息在這里 。
執行存根時,它將檢查所需的例程是否已在內存中。 如果不是,程序將例程加載到內存中。
我不知道您在引用哪本書,但是當前的UNIX OS都無法使用這種方式。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.