編譯鏈結中的 可重定位目標檔案

2021-07-14 15:03:34 字數 1991 閱讀 5441

可重定位目標檔案理解:

資料一:

彙編器所產生的目標檔案至少包括三個區,即文字區(text),資料區(data)和bss區。文字區一般包括程式的**和常量,資料區通常存放全域性變數等內容,bss區用於存放未初始化的變數或作為公共變數儲存空間。在乙個目標檔案中,其text區從位址0開始,隨後是data區,再後面是bss區。而要執行程式,必須裝載到記憶體中,所以這些區的位址需要在記憶體中重新安排,也就是重定位。

資料二:

編譯器編譯後產生的目標檔案是可重定位的程式模組,並不能直接執行,鏈結就是把目標檔案和其他分別進行編譯生成的程式模組(如果有的話)及系統提供的標準庫函式連線在一起,生成可執行的可執行檔案的過程。

重定位是鏈結器在完成符號解析後(知道了各個輸入模組的**段和資料段的大小)的乙個步驟,其作用顧名思義就是重新定位,確定比如指令,全域性變數等在執行時的儲存器位址。       

資料三:

比如說兩個編譯後的可重定位目標檔案obj1.o和obj2.o

在obj1.o裡面定義了乙個全域性變數glob(在obj1裡面記錄了glob相對於該檔案資料段的相對位址), 而obj2.0裡面又引用了這個全域性變數glob。

鏈結的重定位就是要確定在鏈結後的可執行程式中glob的位址,而不是相對於obj1的位址,從而使obj2也能通過位址呼叫glob。

當然重定位並不只是全域性變數,還包括外部函式,指令等執行時位址的確定

資料四:

當你在程式中寫上乙個全域性變數或者是乙個函式時,這個定位過程會經歷幾個階段:

1.在這個目標檔案中的相對定位,乙個目標檔案中會此檔案中的所有函式,變數進行符號描述,比如乙個變數a,它所佔的相對位址是多少?是全域性的?或者是靜態的,或者是外部的??

2.在連線多個目標成乙個可執行檔案時,會再次對這個變數進行重定位,也就是在這個可執行檔案中進行對此變數進行描述,同目標檔案中的描述差不多,只不過此變數不再有外部,內部之分,都成了本地變數,並且會將所有全域性變數存放在一定的邏輯位址中,這是通過連線指令碼檔案與各個目標檔案中的相對位址共同決定的

3.最終的作業系統載入這個可執行檔案時,會對這些變數與函式位址再次進行重定位,其方式就是首先分析這個可執行檔案中的不同段,讀出相應的描述表,然後通過邏輯位址與實體地址進行對映出,最終就將可執行的二進位製碼加進了真實的物理記憶體了,關於分析可執行檔案格式與實體地址的轉換,不同的cpu與作業系統的實現方式會有不同之處

綜上一些資料,自己有了乙個大概的理解,畢竟沒學過編譯原理這方面,只能有個感性的認識,

編譯器把**檔案編譯處理為乙個可執行的二進位制檔案,在window上字尾為ex

e的可執行檔案,linux上生成的可執行檔案沒有字尾來標示,

比如,從乙個c源**檔案變成乙個可執行檔案,這期間編譯器做了很多事情

這些事情依次是:預處理(巨集展開等),編譯(將c**翻譯成為彙編指令),彙編(將彙編**翻譯成機器指令,也叫可重定位目標檔案),

鏈結(鏈結由彙編產生的目標檔案)。關於這幾個事情具體詳細的起到了什麼作用,可參閱博主其他文章或谷歌一下,你全知道!

經過彙編後的目標檔案可以被鏈結成為二進位制可執行檔案。主題來了,鏈結做了什麼?

請看上面的資料三,把多個檔案鏈結成為乙個檔案,之前的各個檔案中的 符號,變數在記憶體中的位址是相對的,

鏈結過程中會把多個檔案的相同型別資料段**段放在一起,所以需要將裡面的符號變數重新安置在乙個確定的記憶體位址中,這就是重定位,

重定位目標檔案,鏈結

原始檔被編譯彙編成可重定位目標檔案,檔案包含資料區,**區,符號表等。符號表表示原始檔中變數和函式在各自區中的位置,所佔大小等資訊。目標檔案中的符號可引用其他可重定位目標檔案中的符號,在聯結器解析符號的時候對這些符號進行聯絡。

目標檔案也可以叫做模組,由函式和變數集合組成。

靜態鏈結庫裡由很多模組組成,且每個模組只有乙個函式組成。乙個模組呼叫靜態鏈結庫,不會把鏈結庫裡的所有模組都鏈結起來,只會鏈結用到的目標模組,減少了最終可執行檔案的記憶體大小。

靜態鏈結庫是把庫的函式載入巢狀在最後的可執行檔案中,而動態鏈結庫是在源程式中呼叫動態鏈結函式dlope,dlsym,dlclos,該函式來獲得動態鏈結庫裡用到的函式指標。

可重定位目標檔案

目標檔案有三種形式 1.可重定位目標檔案 2.可執行目標檔案 3.共享目標檔案 編譯器和彙編器生成可重定位目標檔案 共享目標檔案,聯結器生成可執行目標檔案。在這裡我們首先介紹可重定位目標檔案。可重定位目標檔案 包含二進位制 和資料,可以在編譯時與其他可重定位目標檔案合併起來,建立乙個可執行目標檔案。...

可重定位目標檔案

可重定位目標檔案經由源程式預處理,編譯,彙編之後得到的檔案。其中包括不可讀的二進位制 擴充套件名為.o。現有兩個模組的 main.c int sum int a,int n int array 2 int main sum.c int sum int a,int n return s 一.在linu...

7 4 可重定位目標檔案

下圖展示了乙個典型的elf可重定位目標檔案的格式。elf頭 elf header 以乙個16位元組的序列開始,這個序列描述了生成該檔案的系統的字的大小和位元組順序,elf頭剩下的部分包含幫助鏈結器語法分析和解釋目標檔案的資訊。其中包括elf頭的大小,目標檔案的型別 如可重定位,可執行性,或者共享的 ...