ELF中模組間資料引用的重定位

2021-10-06 22:48:50 字數 1950 閱讀 1711

在模組中進行各類資料引用的方式總共分有:模組內資料、函式訪問,模組間資料、函式訪問,其中模組內的訪問在鏈結時就已經決定了他們的相對偏移,在執行時不再關心這部分的內容,而模組間訪問相對就比較複雜了。

為了復用物理記憶體,發明了pic/pie技術,將資料和指令分開got和plt stub,這樣重定位**只需要修改got的資料部分就可以訪問正確的函式了,elf的plt和got分析了模組間函式訪問過程中的lazy bind機制。

reflink:

lazy binding (also known as lazy linking or on-demand symbol resolution) is the process by which symbol resolution isn't done until a symbol is actually used. 

functions can be bound on-demand, but data references can't.

函式可以在執行時按需進行動態鏈結重定位,但是資料訪問是不行的,必須在程式啟動的時候就完成重定位操作。函式呼叫可以跳轉到plt項,第一次符號引用觸發符號解析,後面的函式呼叫直接就進行跳轉,額外的消耗是多jmp了一次。但是資料訪問就不同了,資料位址是不可執行的,你只能載入資料而不能跳轉到資料位址執行。所以lazy bind對於模組間資料引用是不成立的,它總是bind_now。

各種平台上elf檔案有各種各樣的section名稱:.plt,.got,.plt.got,.got.plt,.rela.plt,不要被名稱迷惑,根據section的型別它總共有三種的:

plt:program independent table,**段,在執行期間不會改變的,是模組間函式跳轉的跳板

got:global offset table,資料段,儲存有模組間函式呼叫的位址和模組間資料訪問的位址,它可能是分開的section:.got,.got.plt,也可能只有乙個.gotrelocation:對section進行重定位的表,在符號重定位的時候需要根據重定位項資訊進行符號解析和修改got中的資訊,got中不管是資料還是函式的位址重定位都需要引用重定位項資訊。

extern

char

**environ;

//訪問libc的資料

intmain

(int argc,

char

**ar**)

{ environ++

;//進行計算

return

0;

開啟linker的除錯:ld_debug=all ~/tmp/a.out

我們看到它經歷了幾個步驟:

26285

: relocation processing: /lib/x86_64-linux-gnu/libc.so.6 (lazy)

...26285

: relocation processing: /home/linux/tmp/a.out (lazy) //lazy bind模式

26285

: symbol=__environ; lookup in file=/lib/x86_64-linux-gnu/libc.so.6 [0]

26285

: binding file /home/linux/tmp/a.out [

0] to /lib/x86_64-linux-gnu/libc.so.6 [0]

: normal symbol `__environ' [glibc_2.2.5]

26285

:26285

: relocation processing: /lib64/ld-linux-x86-64.so.2

...

可重定位的ELF檔案 續

可重定位的elf檔案 續 2011 04 28 10 31 d.重定位表 重定位表中的每個表項都包含了 如何修改某個目標項的資訊,一般,同乙個重定位表中的表項都是描述同乙個節區中符號的修改資訊.下面是重定位表項的資料結構 typedef struct elf32 rel elf32 rel type...

Android的ELF檔案重定位詳解,包括64位

elf檔案格式,主要基於兩種,一種是基於鏈結檢視,鏈結檢視即是基於節 section 來進行解析,一種是基於執行檢視,執行檢視即是基於段 segment 來進行解析。前一種是用於靜態分析的時候,譬如ida載入。後一種是在動態鏈結執行的時候,譬如linker載入。所以修改節資訊實際上是不影響elf正常...

詳解鏈結下的ELF可重定位目標檔案結構

gcc編譯器讀取源程式檔案 c檔案 並把它翻譯成乙個可執行目標檔案,翻譯過程中就包括了鏈結。在現代系統中,鏈結是由叫做鏈結器的程式自動執行的。鏈結是將各種 和資料片段收集並組合成為乙個單一檔案的過程,這個檔案可被載入到記憶體並執行。也就是將所有的檔案彙總為乙個檔案。靜態聯結器以一組可重定位目標檔案和...