鏈接操作的步驟
確定符號參考關系(符號決議)
合并相關(.o)檔案
確定每個符號的新地址
在指令中填入新地址
2,3,4統稱為重定位
ELF三類目標檔案
1.可重定位目標檔案(.o)
每個 .o 檔案都是由對應的 .c 檔案通過編譯器和匯編器生成的,包含二進制代碼資料。可以在編譯時通過與其他可重定位目標檔案(.o)鏈接起來,創建一個可執行目標檔案(a.out).
$ gcc -c test.c
2.可執行目標檔案(a.out)
可執行目標檔案由聯結器生成,包含二進制代碼和資料,可以被直接復制到記憶體并執行。
$gcc -o test test.c
3.共享目標檔案(.so)
一種特殊型別的可重定位目標檔案,可以在加載或者運行時被動態地加載進記憶體并鏈接(動態鏈接)。
ELF可重定位目標檔案
1.可重定位目標檔案格式
ELF頭:包含16位元組標識資訊,檔案型別(.o, exec, .so),機器型別,節頭表的偏移,節頭表的表項大小以及表項個數。
.text:已編譯程式的機器代碼(二進制指令)。(代碼區)
.rodata:只讀資料,比如printf 格式串,switch跳轉表等。
.data:已初始化的全域和靜態變數。區域變數在運行時被保存在堆疊中,既不出現在.data中,也不出現在.bss節中。
.bss:未初始化的全域和靜態變數。僅僅是占位符,不占據任何實際的磁盤空間。
.symtab:一個符號表(symbol table),它存放在程式中被定義和參考的函式和全域變數的資訊。不包含區域變數的表目。
.rel.text:.text節的重定位資訊,用于重新修改代碼段的指令中的地址資訊。
.rel.data:.data的重定位資訊,用于對被模塊使用的或定義的全域變數進行重定位資訊。
.debug:一個除錯符號表,其條目是程式中定義的區域變數和型別定義,程式中定義和參考的全域變數,以及原始的C檔案(gcc -g)。
.strtab:一個字串表,其內容包括.symtab和.debug節中的符號表,以及節頭部中的節名字。字串表就是以null結尾的字串序列。
.line:原始C程式中的行號和.text節中機器指令之間的映射。
節頭表 :每個節的節名和偏移量。
我們可以通過readelf來看一看可重定位目標檔案的ELF頭包含的資訊。先整一段簡單的代碼
//main.o int sum(int *a,int n); int array[2]={1,2}; int mian() { int val=sum(array,2); return val; }
2.ELF頭
我們可以用 readelf -h 命令 來ELF頭資訊
Magic: 魔數,用來指名該檔案是一個 ELF 目標檔案。第一個位元組 7F 是個固定的數;后面的 3 個位元組正是 E, L, F 三個字母的 ASCII 形式。
從中我們可以看到基本資訊,例如 檔案型別,資料格式,ELF頭版本號,作業系統型別(OS/ABI),ELF檔案型別(這里是 可重定位目標檔案),機器平臺型別和目標檔案的版本號 等等。
可重定位檔案不會進行執行,沒有程式頭表,所以:程式頭起點,程式頭大小,Number of program headers(程式頭表中表項個數)皆為0。
Start of section headers:節頭表的偏移量。(本例中720的16進制表示為2d0,所以節頭部表從0x2d0的位置開始。)
該例節頭表有12個節頭,每個節頭64位元組,即節頭表總大小為64*12位元組
字串表索引節頭:節頭部表中字串表(strtab)的索引值。
3.節頭表
我們可以用 readelf -S 命令 來查看節頭表資訊
總共有12個表項每個表項64個位元組,因為是鏈接視圖,所以對應虛擬地址全為零。
在ELF頭中給出一個欄位是指出節頭標的起始位置,這里是0X2d0。就是在指令下面那一行。
只有.text , .data , .bss , .rodata會分配存盤空間。
ELF頭占64位元組即0x40位元組,所以.text的偏移值為0x40加上他的大小即0x21可得其后的偏移值。
節頭表中對所有節的起始位置和大小都記錄了下來。
4.節的分布
現在, 通過ELF頭中節頭表的資訊,以及節頭表中各表項里偏移和大小的值,我們可以畫出檔案中各節的分布
右側數字表示節的大小,左側數字表示偏移。(都是用16進制表示的)
節頭表大小在ELF頭中計算出來。
5.符號表
符號表保存了程式實作或使用的所有全域變數和函式。
Value的值是符號的地址。
Ndx: index,到節頭部表的索引。
(UNDEF表示未定義的符號,ABS表示不該被重定義的符號,COMMON表示未被分配位置未初始化的符號)
uj5u.com熱心網友回復:
謝謝分享, 論壇是用來討論問題的, 基礎請寫到個人博客。轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/134903.html
標籤:基礎類
上一篇:app怎么與后臺服務器保持會話
下一篇:求Tor安轉使用教程
