C 中的連結涉及組合多個目標檔案(.o 檔案)以建立執行檔或共用程式庫。該過程涉及多個步驟,包括地址重定位和符號解析。
連結的一個關鍵功能是_位址重定位_。當編譯器將每個原始檔案編譯為目標檔案時,它會產生包含對其他原始檔案中定義的符號(函數、變數等)的參考的程式碼。但是,在所有目標檔案連結在一起之前,它並不知道這些符號的最終位址。
在連結過程中,連結器會讀取目標檔案中的重定位部分。這些部分包含有關需要在 .text 和 .data 部分中修改哪些位址以指向符號的正確位置的資訊。然後,連結器根據符號的最終位置調整這些位址。
考慮以下範例來說明位址重定位:
; object file hello_world.o .data hello_world db "Hello world!", 10 .text .global _start _start: mov rax, 1 ; sys_write mov rdi, 1 ; stdout mov rsi, hello_world ; placeholder for string address mov rdx, 13 ; number of characters to write syscall
編譯此.o 檔案時,編譯器會插入一個佔位符值(例如0)取得「Hello world!」的位址細繩。連結器讀取此檔案中的.rela.text 部分:
Offset Info Type Sym. Value Sym. Name + Addend 00000000000c 000200000001 R_X86_64_64 0000000000000000 .data + 0
此條目告訴連結器在偏移量0x0c 處(在mov rsi, hello_world 指令內),需要修改一個64 位元值指向.data 部分。
當連結器組合所有目標檔案時,它會調整偏移量處的值0x0c 指向最終可執行檔中字串的正確位址。
以上是C 連結器如何在連結過程中處理地址重定位?的詳細內容。更多資訊請關注PHP中文網其他相關文章!