重定位
(relocation)是把符號引用與符號定義鏈結到一起的過程;比如,當程式呼叫乙個函式時,將從當前執行的指令位址處跳轉到乙個新的指令位址處去執行;然而在編寫程式的過程中,只需要指明所要呼叫的函式名(即符號引用)即可,然後,在重定位過程中,動態鏈結器會把函式名與函式實際所在的位址(即符號定義)聯絡到一起,使得程式能夠知道應該跳轉到**去;
重定位檔案必須知道如何修改其所包含的"節"的內容,在構建可執行檔案或共享目標檔案時,把節中的符號引用轉換成這些符號在程序位址空間中的虛擬位址;包含這些轉換資訊資料的就是"重定位項"(relocation entry);
重定位項的格式使用結構體elf32_rel/elf64_rel描述:
struct
elf32_rel
;struct
elf64_rel
;帶加數的重定位項的格式使用結構體elf32_rela/elf64_rela描述:
struct
elf32_rela
;struct
elf64_rela
;------
字段解釋------
r_offset
:該欄位指明重定位所作用的位置;對於重定位檔案來說,該值是受重定位所作用的儲存單元在節中的位元組偏移量;對於可執行檔案或共享目標檔案來說,該值是受重定位所作用的儲存單元的虛擬位址;
r_info
:該欄位指明重定位所作用的符號表索引和重定位的型別;比如,如果是乙個函式需要重定位,則該字段的值就是被調函式所對應的符號表索引;如果索引值為stn_undef,則未定義索引,那麼重定位過程中將使用0作為符號值;重定位的型別依據處理器的不同而不同;如果一種處理器規定自己引用了乙個重定位項的型別或者符號表索引,則表明這種處理器應用了elf32_r_type/elf64_r_type或elf32_r_sym/elf64_r_sym到其重定位項的r_info欄位;
讀寫r_info欄位的資料
:#define elf32_r_sym(val) ((val)>>8)
#define elf32_r_type(val) ((val)&0xff)
#define elf32_r_info(sym,type) (((sym)<<8)+((type)&0xff))
#define elf64_r_sym(i) ((i)>>32)
#define elf64_r_type(i) ((i)&0xffffffff)
#define elf64_r_info(sym,type) ((((elf64_xword)(sym))<<32)+(type))
r_addend
:該欄位指定了乙個加數,這個加數用於計算需要重定位的域的值;
乙個重定位節需要引用另外兩個節:符號表節和被修改節;在重定位節中,節頭中的字段sh_info和sh_link分別指明了引用關係;不同的目標檔案中,重定位項中的r_offset欄位的含義有所不同;
在重定位檔案中,r_offset欄位含有乙個節偏移量;也就是說,重定位節本身描述的是如何修改檔案中的另乙個節的內容,重定位偏移量r_offset指明了另乙個節中的乙個儲存單元的位址;
在可執行檔案或共享目標檔案中,r_offset欄位含有的是符號定義在程序位址空間中的虛擬位址;可執行檔案和共享目標檔案是用於執行程式,而不是構建程式,所以,對它們來說,更有用的資訊是執行時的記憶體虛擬位址,而不是某個符號定義在檔案中的位置;
重定位型別(relocation types):
重定位型別描述了如何修改被重定位域的對應位;被重定位域是乙個32位的域,占用4個位元組,且位址按4位元組對齊;
可重定位的ELF檔案 續
可重定位的elf檔案 續 2011 04 28 10 31 d.重定位表 重定位表中的每個表項都包含了 如何修改某個目標項的資訊,一般,同乙個重定位表中的表項都是描述同乙個節區中符號的修改資訊.下面是重定位表項的資料結構 typedef struct elf32 rel elf32 rel type...
ELF格式可重定位目標檔案
乙個典型的elf格式的可重定位目標檔案以elf頭開始,還包括 區 資料區,以下是具體形式 elf頭 text 已編譯程式的機器 rodata 唯讀資料 data 已初始化的全域性和靜態c變數 bss 未初始化的全域性和靜態c變數,初始化為0的全域性或靜態變數 symtab 符號表 rel.text ...
04可重定位目標檔案ELF檔案解析
目錄 一 可重定位目標檔案的特點 二 可重定位目標檔案的格式 可被鏈結 合併 生成可執行檔案或共享目標檔案 靜態鏈結庫檔案由若干個可重定位目標檔案組成 包含 資料 已初始化全域性變數和區域性靜態變數.data和未初始化的全域性變數和區域性靜態變數.bss 包含重定位資訊 指出哪些符號引用處需要重定位...