7 4 可重定位目標檔案

2021-08-27 08:49:35 字數 1349 閱讀 2041

下圖展示了乙個典型的elf可重定位目標檔案的格式。elf頭(elf header)以乙個16位元組的序列開始,這個序列描述了生成該檔案的系統的字的大小和位元組順序,elf頭剩下的部分包含幫助鏈結器語法分析和解釋目標檔案的資訊。其中包括elf頭的大小,目標檔案的型別(如可重定位,可執行性,或者共享的),機器型別(如x86-64),節頭部表(section header table)的檔案偏移,以及節頭部表中條目的大小和數量。不同節的位置和大小是由節頭部表描述的,其中目標檔案中每個節都有乙個固定大小的條目。

載入elf頭和節頭部表之間的都是節。乙個典型的elf可重定位目標檔案包含下面的幾個節:

.text:已編譯程式的機器**。

.rodata:唯讀資料,如printf語句中的格式串和開關語句的跳轉表。

.data:已初始化的全域性和靜態c變數。區域性變數在執行時被儲存在棧中,即不出現在.data節中,也不出現在.bss節中。

.bss: 未初始化的全域性變數和靜態c變數,以及所有被初始化位0的全域性或靜態變數。在目標檔案中這個節不佔據實際的空間,它僅僅時乙個佔位符。目標檔案格式區分已初始化和未初始化變數是為了空間效率:在目標檔案中,未初始化變數不占用任何實際的磁碟空間。執行時,在記憶體中分配這些變數,初始值為0.

.symtab:乙個符號表,它存放在程式中定義和引用的函式和全域性變數的資訊,一些程式設計師錯誤的認為必須通過-g選項來編譯乙個程式,才能得到符號表的資訊。實際上每個可重定位目標檔案在.symtab中都有一張符號表(除非程式設計師特意使用strip命令去抹掉它)。然而,和編譯器中的符號表不同,.symtab符號表不包括區域性變數的條目。

.rel .text:乙個.text節中位置的列表,當鏈結器把這個目標檔案和其他檔案組合時,需要修改這些位置。一般而言,任何呼叫外部函式或者引用全域性變數的指令都需要修改。另一方面,呼叫本地函式的指令則不需要修改。注意,可執行目標檔案中並不需要重定位資訊,因此通常省略,除非使用者顯示的指示鏈結器包含這些資訊。

.rel .data:被模組引用或定義的所有全域性變數的重定位資訊,一般而言,任何已初始化的全域性變數,如果它的初始值是乙個全域性變數位址或者外部定義函式的位址,都需要被修改。

.debug:乙個除錯符號表,其條目是程式中定義的區域性變數和型別定義,程式中定義和引用的全域性變數,以及原始的c原始檔,只有以-g選項呼叫編譯器驅動程式時,才會得到這張表。

.line:原始c源程式中的行號和.text節中機器指令之間的對映。只有以-g選項呼叫編譯器驅動程式時,才會得到這張表。

.strtab:乙個字串表,其內容包括.symtab和.debug節中的符號表,以及節頭部中的節名字。字串表就是以null結尾的字串的序列。

可重定位目標檔案

目標檔案有三種形式 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...

可重定位目標檔案解析

程式 如下 最簡單的hello.c include intmain 我們首先生成可重定位目標檔案 gcc c hello.c這是有關可重定位目標檔案的結構圖 從mooc ppt上所截 計算機系統基礎 一 第十周第三講 讓我們看一下elf的檔案大體的資訊 選取幾個解釋一下 type rel 可重定位檔...