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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > linux >内容正文

linux

Linux下生成动态链接库是否必须使用 -fPIC 的问题

發(fā)布時間:2023/12/9 linux 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux下生成动态链接库是否必须使用 -fPIC 的问题 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

From: http://www.linuxidc.com/Linux/2011-06/37268.htm

?

在 Linux 下制作動態(tài)鏈接庫,“標(biāo)準(zhǔn)” 的做法是編譯成位置無關(guān)代碼(Position Independent Code,PIC),然后鏈接成一個動態(tài)鏈接庫。經(jīng)常遇到的一個問題是 -fPIC 是不是必需,因?yàn)楹孟癫患咏?jīng)常也能正常運(yùn)行,只是創(chuàng)建 .so 的時候會有一個警告。

搜索、試驗(yàn)了一下,答案似乎是這樣:

(1) 通常的建議是始終加上 -fPIC 生成位置無關(guān)代碼;

(2) AMD64 下,必須使用位置無關(guān)代碼,否則連接失敗:

relocation R_X86_64_32S against `a local symbol' can not be used when making a shared object; recompile with -fPIC

(3) IA32 下,連接成功,但有警告:

warning: creating a DT_TEXTREL in object.

這樣的 .so 文件可以完全正常工作。

可執(zhí)行文件在鏈接時就知道每一行代碼、每一個變量會被放到線性地址空間的什么位置,因此這些地址可以都作為常數(shù)寫到代碼里面。對動態(tài)庫,這就不行了,這要等到加載時才知道。無非下面兩種方法:

(1) 可重定位代碼(relocatable code):Windows DLL 以及不使用 -fPIC 的 Linux SO。

生成動態(tài)庫時假定它被加載在地址 0 處。加載時它會被加載到一個地址(base),這時要進(jìn)行一次重定位(relocation),把代碼、數(shù)據(jù)段中所有的地址加上這個 base 的值。這樣代碼運(yùn)行時就能使用正確的地址了。

(2) 位置無關(guān)代碼(position independent code):使用 -fPIC 的 Linux SO。

這樣的代碼本身就能被放到線性地址空間的任意位置,無需修改就能正確執(zhí)行。通常的方法是獲取指令指針(如 IA32 的 EIP 寄存器)的值,加上一個偏移得到全局變量/函數(shù)的地址。

PIC vs. relocatable:

(1) PIC 的缺點(diǎn)主要就是代碼有可能長一些。例如 IA32,由于不能直接使用 [EIP+constant] 這樣的尋址方式,甚至不能直接將 EIP 的值交給其他寄存器,要用到 GOT(global offset table)來定位全局變量和函數(shù)。這樣導(dǎo)致代碼的效率略低。

(2) PIC 的加載速度稍快,因?yàn)椴恍枰鲋囟ㄎ弧?/p>

(3) 多個進(jìn)程引用同一個 PIC 動態(tài)庫時,可以共用內(nèi)存。這一個庫在不同進(jìn)程中的虛擬地址不同,但操作系統(tǒng)顯然會把它們映射到同一塊物理內(nèi)存上。對于可重定位代碼,則必須為每個庫都在物理內(nèi)存中復(fù)制一份副本,因?yàn)樾枰薷钠渲械牡刂贰.?dāng)然,主流現(xiàn)代操作系統(tǒng)都啟用了分頁內(nèi)存機(jī)制,這使得重定位時可以使用 COW(copy on write)來節(jié)省內(nèi)存(32 位 Windows 就是這樣做的);然而,頁面的粒度還是比較大的(例如 IA32 上是 4KiB),至少對于代碼段來說能節(jié)省的相當(dāng)有限。

注:對于 AMD64,由于 AMD64 實(shí)現(xiàn)了 [RIP+constant] 的尋址方式,第 (1) 點(diǎn)不成立。

這樣,把動態(tài)庫編譯成 PIC 只有好處沒有壞處,因而 Linux AMD64 要求用于生成動態(tài)庫的目標(biāo)文件必須使用 -fPIC 編譯也合情合理了。

創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎

總結(jié)

以上是生活随笔為你收集整理的Linux下生成动态链接库是否必须使用 -fPIC 的问题的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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