回覆列表
  • 1 # Affgcff

    使用 -fPIC 選項,會生成 PIC 程式碼。.so 要求為 PIC,以達到動態連結的目的,否則,無法實現動態連結。non-PIC 與 PIC 程式碼的區別主要在於 access global data, jump label 的不同。比如一條 access global data 的指令,non-PIC 的形勢是:ld r3, var1PIC 的形式則是: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 一樣。

  • 中秋節和大豐收的關聯?
  • 試管技術出生的寶寶健康嗎?