程式設計師的自我修養(六)靜態鏈結 符號解析與重定位

2021-09-21 07:34:32 字數 949 閱讀 3783

符號解析與重定位是靜態鏈結的核心內容。

重定位表

重定位表專門用來儲存與重定位相關的資訊,它在elf檔案中往往是乙個或多個段。

用objdump -r ***.o檢視目標檔案的重定位表

每個要被重定位的地方叫乙個重定位入口。在這裡,**段的重定位入口有6個。

relocation records for [.txt]代表這個重定位表示**段的重定位表。

offset:重定位入口的偏移,表示該入口在要被重定位的段中的位置。對於可重定位檔案來說,這個值是該重定位入口所要修正的位置的第乙個位元組相對於段起始的偏移;對於可執行檔案或共享物件檔案來說,這個值是重定位入口索要修正的位置的第乙個位元組的虛擬位址。

用readelf -s ***.o檢視***.o的符號表

und:undefined未定義型別。這種未定義的符號是因為該目標檔案中有關於它的重定位項。所以在鏈結器掃瞄完所有的輸入目標檔案之後,所有這些未定義的符號都應該能夠在全域性符號表中找到,否則鏈結器就報符號未定義錯誤。

定址方式的區別:

對於32位x86平台下的elf檔案的重定位入口所修正的指令定址方式只有兩種(這兩種指令修正方式每個被修正的位置的長度都是32位,即4個位元組):

修正位址

s:符號的實際位置

p:被修正的位置(相對於段開始的偏移量或者虛擬位址)

a:儲存在被修正位置的值

看到這一部分真的有點懵了。。。明天開始大概看一下彙編的基礎知識吧。。。各種指令有點暈_(¦3」∠)_

《程式設計師的自我修養》筆記 靜態鏈結

在通過編譯和彙編後,就生成了目標檔案,鏈結就是把這些目標檔案加工後合併成乙個輸出檔案的過程。鏈結過程可以分為兩步 第一步 空間與位址分配。掃瞄所有的輸入目標檔案,獲得它們每個各個段的長度 屬性和位置,並且將輸入目標檔案中的符號表中所有 的符號定義和符號引用收集起來,統一放到乙個全域性符號表。這一步中...

程式設計師的自我修養四靜態鏈結

真正了不起的程式設計師對自己的程式的每乙個位元組都了如執掌。a.c extern intshared int main 全域性符號 b.c int shared 1 全域性符號 void swap int a,int b 全域性符號 對於鏈結器來說,整個鏈結過程中,它就是將幾個輸入目標檔案加工後合併...

程式設計師的自我修養 編譯和鏈結

hello world程式hello.c include int main 在linux下,使用gcc編譯和執行hello world程式時,只需使用最簡單的命令。gcc hello hello.c hello hello world 事實上,上述過程可以分解為4個步驟,分別是預處理 prepres...