2012-10-01 39 views

回答

9

按我的理解,每個可執行對象都有自己的「查找範圍」:

  • 主可執行程序通常是在「全球」查找範圍內的第一個對象。這意味着主可執行文件中定義的符號會覆蓋依賴共享庫中的符號。使用LD_PRELOAD工具添加的共享對象被添加到全局查找範圍,緊跟在主可執行文件之後。
  • 但是,如果要加載的共享對象使用DF_SYMBOLIC標誌,那麼符號引用該對象內的起源將查找定義在全球範圍內查找搜索前的對象之內。
  • 使用dlopen()打開的共享對象可能有其自己的依賴關係。如果RTLD_GLOBAL標誌在調用dlopen()期間未設置,則這些依賴項會被添加到該對象的查找範圍中,但不會影響全局查找範圍。如果RTLD_GLOBAL標誌被傳遞給dlopen(),那麼共享對象(及其依賴關係)將被添加到「全局」查找範圍,從而改變後續符號查找的行爲。

烏利齊·德雷珀指南「How to Write Shared Libraries」推薦閱讀關於這一主題。

+0

爲了完整性:除非使用rdynamic選項(或類似選項)編譯它,否則不會將主要可執行文件的符號導出到動態符號表中, – debuti

4

解析共享庫的符號時,加載器首先在'main executable'中進行搜索(讓主執行體覆蓋定義...)或者什麼?

是的,正好。動態加載器具有已加載的ELF對象的鏈表(列表頭爲_r_dynamic.r_map),併線性查找該列表中的對象的動態符號表,直到找到正在查找的符號定義。

列表頭始終指向主可執行文件。如果給定的符號從主可執行文件導出,那麼它(幾乎)總是「勝出」(覆蓋其他定義)。

但是,請注意-Bsymbolic鏈接器標誌有點改變圖片。