日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

ELF 文件 动态链接 - 地址无关代码(GOT)

發(fā)布時(shí)間:2025/5/22 编程问答 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ELF 文件 动态链接 - 地址无关代码(GOT) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

Linux 系統(tǒng)中,ELF動(dòng)態(tài)鏈接文件被稱為 動(dòng)態(tài)共享對(duì)象(DSODynamic Shared Object),簡(jiǎn)稱共享對(duì)象

文件拓展名為“.so”

?

動(dòng)態(tài)鏈接下 一個(gè)程序可以被分成若干個(gè)文件:程序的主要部分 - 可執(zhí)行文件 和 程序所依賴的共享對(duì)象(一個(gè)或多個(gè).so文件),它們都可稱作為程序的模塊。

動(dòng)態(tài)鏈接文件(共享對(duì)象)的裝載地址為0x00000000;這并非工作時(shí)的實(shí)際地址,實(shí)際地址由裝載器根據(jù)當(dāng)前進(jìn)程地址空間的空閑情況來(lái)動(dòng)態(tài)分配一塊足夠大的虛擬地址空間給共享對(duì)象。

?

裝載時(shí)重定位

基本思路:在鏈接時(shí)對(duì)所有的絕對(duì)地址的引用不作重定位,而把這一步放在裝載時(shí)完成。一旦模塊裝載完成,既目標(biāo)地址確定,那么系統(tǒng)將對(duì)程序中的所有絕對(duì)地址的引用進(jìn)行重定位。

?

靜態(tài)鏈接時(shí)的重定位稱為 鏈接時(shí)重定位(Link Time Relocation)

動(dòng)態(tài)鏈接時(shí)的重定位稱為 裝載時(shí)重定位(Load Time Relocation) gcc -shared

?

然而光有裝載時(shí)重定位也不能解決所有問(wèn)題,因?yàn)閷?duì)于動(dòng)態(tài)鏈接文件來(lái)講,它時(shí)可以分為可修改數(shù)據(jù)部分和不可修改數(shù)據(jù)部分,如果只有裝載重定位,那每個(gè)程序必須都有一個(gè)共享對(duì)象的副本,這樣會(huì)很浪費(fèi)內(nèi)存

這樣就引入來(lái)下一個(gè)話題

?

地址無(wú)關(guān)代碼 (gcc -shared -fPIC)

基本思想: 把指令中需要被修改的部分分離出來(lái),跟數(shù)據(jù)部分放在一起,這樣指令部分就保持不變了,而數(shù)據(jù)部分為每個(gè)進(jìn)程都有一個(gè)副本,

這就是地址無(wú)關(guān)代碼(PIC, Position-independent Code)技術(shù)

?

共享對(duì)象模塊內(nèi)的地址引用分為四種情況:

1. 模塊內(nèi)部調(diào)用或跳轉(zhuǎn):

    它們之間位置固定,使用相對(duì)地址調(diào)用。

2. 模塊內(nèi)部數(shù)據(jù)訪問(wèn)

    同樣使用相對(duì)尋址(使用當(dāng)前(指令地址)PC + 偏移量)

3. 模塊與模塊之間的數(shù)據(jù)訪問(wèn)(重點(diǎn))

    模塊之間的數(shù)據(jù)訪問(wèn),其目標(biāo)地址需要等到裝載后才能確定。

    這里的基本思想時(shí)將這部分與地址相關(guān)的指令的當(dāng)前地址放入到數(shù)據(jù)段里面。

    ELF 的做法是在數(shù)據(jù)段中建立了一個(gè) 指向這些變量的指針數(shù)組 ,也被稱為 全局偏移表(GOT, Global Offset Table),當(dāng)代碼需要引用該全局變量時(shí),通過(guò)GOT間接引用,

    即GOT中記錄著該外部函數(shù)真正的地址,裝載器在做動(dòng)態(tài)鏈接時(shí),會(huì)查找每個(gè)外部符號(hào)的地址,然后填充到GOT的對(duì)應(yīng)的項(xiàng)中。

?

    GOT 如何做到與指令無(wú)關(guān)的呢?(在.so 文件中對(duì)應(yīng) .got 段)

    1.?模塊在編譯期可以確定模塊內(nèi)部變量相對(duì)與當(dāng)前指令的偏移,同樣在編譯期也可以確定GOT相對(duì)于當(dāng)前指令的偏移。確定GOT的位置和確定內(nèi)部變量的位置方法上時(shí)一樣的,通過(guò)

     得到PC值然后加上一個(gè)偏移量即可得到GOT的位置。當(dāng)然GOT中的每個(gè)地址對(duì)應(yīng)于哪個(gè)符號(hào)(變量,函數(shù)都是符號(hào))由編譯期決定。

?

4. 模塊間跳用和跳轉(zhuǎn)

    此時(shí)與3.中方法類似,只是對(duì)應(yīng)的GOT的位置保存的時(shí)目標(biāo)函數(shù)的地址,通過(guò)GOT實(shí)現(xiàn)間接跳轉(zhuǎn)

?

地址無(wú)關(guān)小結(jié):

?

                    各種引用方式
?指令跳轉(zhuǎn)和調(diào)用?數(shù)據(jù)訪問(wèn)
模塊內(nèi)部?相對(duì)跳轉(zhuǎn)調(diào)用?相對(duì)訪問(wèn)
模塊外部GOT間接跳轉(zhuǎn)訪問(wèn)GOT間接跳轉(zhuǎn)訪問(wèn)

?

轉(zhuǎn)載于:https://www.cnblogs.com/gradyblog/p/8963785.html

總結(jié)

以上是生活随笔為你收集整理的ELF 文件 动态链接 - 地址无关代码(GOT)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。