gcc -fPIC选项
生活随笔
收集整理的這篇文章主要介紹了
gcc -fPIC选项
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
使用 -fPIC 選項,會生成 PIC 代碼。.so 要求為 PIC,以達到動態鏈接的目的,否則,無法實現動態鏈接。
non-PIC 與 PIC 代碼的區別主要在于 access global data, jump label 的不同。 比如一條 access global data 的指令, non-PIC 的形勢是:ld r3, var1 PIC 的形式則是:ld r3, var1-offset@GOT,意思是從 GOT 表的 index 為 var1-offset 的地方處 指示的地址處裝載一個值,即 var1-offset@GOT 處的4個 byte 其實就是 var1 的地址。這個地址只有在運行的時候才知道, 是由 dynamic-loader(ld-linux.so) 填進去的。
再比如 jump label 指令 non-PIC 的形勢是:jump printf ,意思是調用 printf。 PIC 的形式則是:jump printf-offset@GOT,意思是跳到 GOT 表的 index 為 printf-offset 的地方處 指示的地址去執行,這個地址處的代碼擺放在 .plt section,每個外部函數對應一段這樣的代碼,其功能是呼叫 dynamic-loader(ld-linux.so) 來查找函數的地址(本例中是 printf),然后將其地址寫到 GOT 表的 index 為 printf-offset 的地方, 同時執行這個函數。這樣,第2次呼叫 printf 的時候,就會直接跳到 printf 的地址,而不必再查找了。
GOT 是 data section, 是一個 table, 除專用的幾個 entry,每個 entry 的內容可以再執行的時候修改; PLT 是 text section, 是一段一段的 code,執行中不需要修改。 每個 target 實現 PIC 的機制不同,但大同小異。比如 MIPS 沒有 .plt, 而是叫 .stub,功能和 .plt 一樣。
可見,動態鏈接執行很復雜,比靜態鏈接執行時間長;但是,極大的節省了 size,PIC 和動態鏈接技術是計算機發展史上非常重要的一個里程碑。
non-PIC 與 PIC 代碼的區別主要在于 access global data, jump label 的不同。 比如一條 access global data 的指令, non-PIC 的形勢是:ld r3, var1 PIC 的形式則是:ld r3, var1-offset@GOT,意思是從 GOT 表的 index 為 var1-offset 的地方處 指示的地址處裝載一個值,即 var1-offset@GOT 處的4個 byte 其實就是 var1 的地址。這個地址只有在運行的時候才知道, 是由 dynamic-loader(ld-linux.so) 填進去的。
再比如 jump label 指令 non-PIC 的形勢是:jump printf ,意思是調用 printf。 PIC 的形式則是:jump printf-offset@GOT,意思是跳到 GOT 表的 index 為 printf-offset 的地方處 指示的地址去執行,這個地址處的代碼擺放在 .plt section,每個外部函數對應一段這樣的代碼,其功能是呼叫 dynamic-loader(ld-linux.so) 來查找函數的地址(本例中是 printf),然后將其地址寫到 GOT 表的 index 為 printf-offset 的地方, 同時執行這個函數。這樣,第2次呼叫 printf 的時候,就會直接跳到 printf 的地址,而不必再查找了。
GOT 是 data section, 是一個 table, 除專用的幾個 entry,每個 entry 的內容可以再執行的時候修改; PLT 是 text section, 是一段一段的 code,執行中不需要修改。 每個 target 實現 PIC 的機制不同,但大同小異。比如 MIPS 沒有 .plt, 而是叫 .stub,功能和 .plt 一樣。
可見,動態鏈接執行很復雜,比靜態鏈接執行時間長;但是,極大的節省了 size,PIC 和動態鏈接技術是計算機發展史上非常重要的一個里程碑。
總結
以上是生活随笔為你收集整理的gcc -fPIC选项的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: android 本地数据库sqlite的
- 下一篇: 基于词典的情感分析实验