so库方法原理
動(dòng)態(tài)庫(kù)
So庫(kù),又動(dòng)態(tài)名庫(kù),是Linux下最常見(jiàn)的文件之一,是一種ELF文件。這種so庫(kù)是程序運(yùn)行時(shí),才會(huì)將這些需要的代碼拷貝到對(duì)應(yīng)的內(nèi)存中。但程序運(yùn)行時(shí),這些地址早已經(jīng)確定,那程序引用so庫(kù)中的這些代碼地址如何確定呢,這就是這次要整理學(xué)習(xí)的內(nèi)容,即so庫(kù)的在鏈接和執(zhí)行時(shí)的加載過(guò)程。

靜動(dòng)態(tài)庫(kù)
先聊靜態(tài)庫(kù)。為了程序更加優(yōu)雅和高效,每一個(gè)程序的完成都是采用分而治之的方法,即同一個(gè)程序或者項(xiàng)目每個(gè)程序員都會(huì)完成不同的功能,有的功能是可復(fù)用的,而對(duì)于一些公共的可復(fù)用的功能,會(huì)使用庫(kù)的形式來(lái)完成。比如我們?cè)诓煌K中多次用到了一個(gè)方法ar_public(),我們就可以將其包裝到一個(gè)公共的文件里面,這樣就如果其他的地方有調(diào)用就可以把引用這個(gè)公共文件從而調(diào)用這個(gè)方法,這樣就有了靜態(tài)庫(kù)。簡(jiǎn)單來(lái)說(shuō)靜態(tài)庫(kù)是鏈接的時(shí)候?qū)?kù)中所用到的程序拷貝進(jìn)來(lái),這樣即使在執(zhí)行階段吧對(duì)應(yīng)的庫(kù)刪掉都沒(méi)有關(guān)系,因?yàn)榇藭r(shí)對(duì)應(yīng)方法的真實(shí)內(nèi)容已經(jīng)被拷貝過(guò)來(lái)了。但是雖然能做到方法共用,但帶來(lái)最大的一個(gè)問(wèn)題是如果是同一個(gè)項(xiàng)目的不同模塊使用的話(huà),使用的每個(gè)模塊都會(huì)把這些拷貝過(guò)來(lái),這樣會(huì)使得應(yīng)用的內(nèi)存增大。也恰恰是由于會(huì)將靜態(tài)庫(kù)的這些方法拷貝進(jìn)來(lái)如果靜態(tài)庫(kù)發(fā)生改變的話(huà)那程序需要重新編譯。
為了解決上面的問(wèn)題,于是又有了一個(gè)動(dòng)態(tài)庫(kù)的概念。動(dòng)態(tài)庫(kù),又稱(chēng)共享庫(kù)鏈接的時(shí)候它只包含需要的函數(shù)引用表,只有在執(zhí)行的時(shí)候那些需要的函數(shù)才能被拷貝到內(nèi)存中,而且在操作系統(tǒng)使用的是虛擬內(nèi)存,使得一份共享庫(kù)駐留在內(nèi)存中被多個(gè)程序使用,也同時(shí)節(jié)約了內(nèi)存。
位置無(wú)關(guān)(PIC)
大家都知道,可執(zhí)行文件在執(zhí)行期的時(shí)候內(nèi)存地址已經(jīng)都確定了,而上面說(shuō)的只有執(zhí)行時(shí)才會(huì)確定那些函數(shù)地址拷貝到內(nèi)存中,那基于這個(gè)特點(diǎn)大家第一想道的實(shí)現(xiàn)就是像那些段一樣預(yù)留一個(gè)空間,但是這樣做的一個(gè)最大問(wèn)題就是會(huì)造成空間浪費(fèi),我們可以readelf去看下so庫(kù)中的地址情況,從圖一來(lái)看和data相關(guān)的地址都不是絕對(duì)地址(由于程序的起始加載地址都是從data開(kāi)始,所以data相關(guān)的頭如果不是絕對(duì)地址則可以認(rèn)為加載的地址不固定)。
在動(dòng)態(tài)共享庫(kù)中,如果庫(kù)里面的代碼發(fā)生改變,重新加載進(jìn)來(lái)之后,我們必須保證它放到修改前的位置 ,否則我們還要為它找一個(gè)新的位置。而我們對(duì)于這個(gè)修改之后希望將動(dòng)態(tài)庫(kù)編譯成可以在任意位置加載無(wú)需linker進(jìn)行修改,這個(gè)叫做位置無(wú)關(guān)代碼即PIC,也就是生成so庫(kù)的-fPIC的那個(gè)PIC(這個(gè)指令就表示生成位置無(wú)關(guān)代碼)。那PIC的原理是如何實(shí)現(xiàn)的呢,我們都知道數(shù)據(jù)段和代碼段的距離在運(yùn)行時(shí)是可以確定的,其中就是利用這一點(diǎn)來(lái)做地址定位的。
靜態(tài)分析:
Linux Dynamic Shared Library && LD Linker
https://www.cnblogs.com/cdcode/p/5551649.html
動(dòng)態(tài)鏈接
聊聊Linux動(dòng)態(tài)鏈接中的PLT和GOT(1)——何謂PLT與GOT
_dl_runtime_resolve源碼分析
【ARM】安卓SO中GOT REL PLT 作用與關(guān)系
深入了解GOT,PLT和動(dòng)態(tài)鏈接
總結(jié)
- 上一篇: 走到了尽头是什么歌呢
- 下一篇: 从广州坐高铁到深圳要多少钱?多少时间