動態連結相關知識

來源:互聯網
上載者:User

標籤:動態連結

符號重定位

講動態連結之前,得先說說符號重定位。

c/c++ 程式的編譯是以檔案為單位進行的,因此每個 c/cpp 檔案也叫作一個編譯單元(translation unit), 源檔案先是被編譯成一個個目標檔案, 再由連結器把這些目標檔案組合成一個可執行檔或庫,連結的過程,其核心工作是解決模組間各種符號(變數,函數)相互引用的問題,對符號的引用本質是對其在記憶體中具體地址的引用,因此確定符號地址是編譯,連結,載入過程中一項不可缺少的工作,這就是所謂的符號重定位。本質上來說,符號重定位要解決的是當前編譯單元如何訪問「外部」符號這個問題。

因為編譯是以源檔案為單位進行的,編譯器此時並沒有一個全域的視野,因此對一個編譯單元內的符號它是無力確定其最終地址的,而對於可執行檔來說,在現代作業系統上,程式載入啟動並執行地址是固定或可以預期的,因此在連結時,連結器可以直接計算分配該檔案內各種段的絕對或相對位址。所以對於可執行檔來說,符號重定位是在連結時完成的(如果可執行檔引用了動態庫裡的函數,則情況稍有不同)。但對於動態連結程式庫來說,因為動態庫的載入是在運行時,且載入的地址不固定,因此沒法事先確定該模組的起始地址,所以對動態庫的符號重定位,只能延遲。

符號重定位既指在當前目標檔案內進行重定位,也包括在不同目標檔案,甚至不同模組間進行重定位,這裡面有什麼不同嗎?如果是同一個目標檔案內,或者在同一個模組內,連結後,各個符號的相對位址就已經確定了,看起來似乎不用非得要知道最後的絕對位址才能引用這些符號,這說起來好像也有道理,但事實不是這樣,x86 上 mov 之類訪問程式中資料區段的指令,它要求運算元是絕對位址,而對於函數調用,雖然是以相對位址進行調用,但計算相對位址也只限於在當前目標檔案內進行,跨目標檔案跨模組間的調用,編譯期也是做不到的,只能等連結時或載入時才能進行相對位址的計算,因此重定位這個過程是不能缺少的,事實上目前來說,對於動態連結即使是當前目標檔案內,如果是全域非靜態函數,那麼它也是需要進行重定位的。

註:

動態連結,在可執行檔裝載時或運行時,由作業系統的裝載程式載入庫。大多數作業系統將解析外部參考(比如庫)作為載入過程的一部分。在這些系統上,可執行檔包含一個叫做import directory的表,該表的每一項包含一個庫的名字。根據表中記錄的名字,裝載程式在硬碟上搜尋需要的庫,然後將其載入到記憶體中預先不確定的位置,之後根據載入庫後確定的庫的地址更新可執行程式。可執行程式根據更新後的庫資訊調用庫中的函數或引用庫中的資料。這種類型的動態載入成為裝載時載入 ,被包括Windows和Linux的大多數系統採用。裝載程式在載入應用軟體時要完成的最複雜的工作之一就是載入時連結。

其他動作系統可能在運行時解析引用。在這些系統上,可執行程式叫用作業系統API,將庫的名字,函數在庫中的編號和函數參數一同傳遞。作業系統負責立即解析然後代表應用調用合適的函數。這種動態連結叫做運行時連結 。因為每個調用都會有系統開銷,運行時連結要慢得多,對應用的效能有負面影響。現代作業系統已經很少使用運行時連結。
  可以動態連結的庫,在Windows上是dynamic link library (DLL),在UNIX或Linux上是Shared Library。庫檔案是預先編譯連結好的可執行檔,儲存在電腦的硬碟上。大多數情況下,同一時間多個應用可以使用一個庫的同一份拷貝,作業系統不需要載入這個庫的多個執行個體。
  動態連結的最大缺點是可執行程式依賴分別儲存的庫檔案才能正確執行。如果庫檔案被刪除了,移動了,重新命名了或者被替換為不相容的版本了,那麼可執行程式就可能工作不正常。這就是常說的DLL-hell。

g++編譯參數:

-shared 該選項指定產生動態串連庫(讓連接器產生T類型的匯出符號表,有時候也產生弱串連W類型的匯出符號),不用該標誌外部程式無法串連。相當於一個可執行檔。

-fPIC:表示編譯為位置獨立的代碼,不用此選項的話編譯後的代碼是位置相關的所以動態載入時是通過代碼拷貝的方式來滿足不同進程的需要,而不能達到真正程式碼片段共用的目的。 

-L.:表示要串連的庫在目前的目錄中 

-l Detour:編譯器尋找動態串連庫時有隱含的命名規則,即在給出的名字前面加上lib,後面加上.so來確定庫的名稱

-I 項目中include包含的標頭檔尋找路徑



本文出自 “小止” 部落格,請務必保留此出處http://10541556.blog.51cto.com/10531556/1814841

動態連結相關知識

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.