即可執行可鏈結格式,也就是對可重定位目標檔案進行解析的格式。
而我們知道從源**到可執行目標檔案一般要經歷以下幾個步驟:
main.c-----預處理(cpp)----->main.i------編譯(ccl)----->main.s-----彙編(as)----->main.o-----鏈結(ld)----->main(可執行檔案)而可重定位目標檔案是其中的.o檔案,它包括二進位制**和資料,同時在編譯時將所有的可重定位目標檔案合併為可執行目標檔案,由上文可知,每個.o檔案是由對應的.c檔案生成,且每個.o的資料和檔案都是從0開始的。
接下來介紹elf。
elf有兩種檢視分別為鏈結檢視和執行檢視,對應不同的目標檔案。
@elf的鏈結檢視(來自中國大學mooc南京大學袁春風老師的ppt):
對應可重定位的目標檔案
@elf的執行檢視(來自中國大學mooc南京大學袁春風老師的ppt):
對應可執行的目標檔案
現在通過ubantu跑幾個程式加深理解
main.c:
/* main.c */
/* $begin main */
intsum
(int
*a,int n)
;int array[2]
=;intmain()
/* $end main */
在終端介面輸入 readelf -h 可以看到如下資訊,即elf的頭資訊:
注意上面的magic,其後的7f 45 4c 46是elf的魔數,魔數就是檔案開頭幾個位元組通常用來確定檔案的型別或格式的數,通常a.out的魔數是01h 07h,pe格式下為4dh 5ah。在載入或讀取檔案時,一般用魔數確定檔案型別是否正確。
接著我們可以看到mian.o的型別是32位版本的,資料為補碼是小端模式執行的,版本為1,作業系統是unix - system v,版本型別為rel(可重定位檔案),機器為intel 80386架構。
入口位址為0,也即是可重定位目標檔案的位址為0。
程式頭表偏移量為0,大小為0,表項個數為0,說明程式頭表不存在,也就是說明了可重定位檔案是只能用於鏈結,而不能用於載入的
start of section headers給出了節頭表的起始位置是276位元組,位於elf頭0處開始往下數276個位元組,節頭表項有12個,每個是40個位元組(一共有12* 40b)
elf佔52b
最後一行指出第9行是字串表
現在用另一條命令:readelf -s main.o
得到的結果如圖:
該命令用來讀節頭表資訊
在表的開始前會說明一共有12個節頭資訊,且節頭表的起始位置在 0x114
addr一欄可以看到位址都是0,因為是可重定位檔案,所以不會執行,位址為0
off是偏移量,即offset。size指出了該節有多大,接下來指出是否可裝入,可執行,對齊方式等等
有四個節將會分配空間,分別為.text可執行,.date和.bss可讀可寫,.rodata可讀,此外其他的節在執行時都不會載入到暫存器中,只作為輔助鏈
在這裡我們可以看到.text起始位置off是34正好呼應了我們上面所講elf頭佔52b=0x34b
在表中可以看到0-11共12個節的情況,第0個節為空,且每乙個表象都是64個位元組的資料結構。
資料結構:(來自mooc袁春風老師的計算機系統基礎(一)的課件)
接下來用readelf -s main.o得到如下資訊:
從圖中可以看出這是符號表的資訊
從中間可以看到main函式放在第一節對應.text,array放在第三節的.data中,而sum是乙個未定義的符號
到此,大概就知道重定位目標檔案是咋解析的了,而重定位其實是相當於給其中的符號賦乙個新位址,而原來的位址是0。
可重定位目標檔案解析
程式 如下 最簡單的hello.c include intmain 我們首先生成可重定位目標檔案 gcc c hello.c這是有關可重定位目標檔案的結構圖 從mooc ppt上所截 計算機系統基礎 一 第十周第三講 讓我們看一下elf的檔案大體的資訊 選取幾個解釋一下 type rel 可重定位檔...
04可重定位目標檔案ELF檔案解析
目錄 一 可重定位目標檔案的特點 二 可重定位目標檔案的格式 可被鏈結 合併 生成可執行檔案或共享目標檔案 靜態鏈結庫檔案由若干個可重定位目標檔案組成 包含 資料 已初始化全域性變數和區域性靜態變數.data和未初始化的全域性變數和區域性靜態變數.bss 包含重定位資訊 指出哪些符號引用處需要重定位...
可重定位目標檔案
目標檔案有三種形式 1.可重定位目標檔案 2.可執行目標檔案 3.共享目標檔案 編譯器和彙編器生成可重定位目標檔案 共享目標檔案,聯結器生成可執行目標檔案。在這裡我們首先介紹可重定位目標檔案。可重定位目標檔案 包含二進位制 和資料,可以在編譯時與其他可重定位目標檔案合併起來,建立乙個可執行目標檔案。...