首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C語言靜態鏈接實戰圖解:從目標文件到可執行文件的地址重定位全記錄

     編輯:關於C語言

C語言靜態鏈接實戰圖解:從目標文件到可執行文件的地址重定位全記錄

承接上篇理論,本文以實際 objdump 輸出圖片為證,逐幀拆解 a.o、b.o 鏈接為 ab 的完整地址變遷過程,視覺化呈現重定位魔法。

編譯與鏈接命令

gcc -c a.c b.c          # 生成 a.o, b.o
gcc a.o b.o -o ab       # 靜態鏈接生成 ab

1. 目標文件段佈局(基址 0)

a.o 段表

b.o 段表

a.o 符號表

b.o 符號表

  • a.o、b.o 的 .text、.data、.bss 起始地址均為 0x0
  • 符號表中 shared、swap 在各自文件內的偏移可見

2. 可執行文件段佈局(基址 0x08048000)

ab 段表

  • Linux 32位 ELF 默認加載地址 0x08048000
  • 合併後 .text 從 0x08048000 開始,.data 從 0x08049158 開始

3. 重定位表:待修正位置清單

a.o 重定位表

重定位類型表

  • 偏移 0x11:R_386_32 類型,符號 shared(絕對地址修正)
  • 偏移 0x20:R_386_PC32 類型,符號 swap(相對地址修正)

4. 重定位前機器碼(a.o 反彙編)

a.o 反彙編

a.o 機器碼細節

  • 0x11 處:c7 44 24 04 00 00 00 00 → movl $0x0, 0x4(%esp),shared 佔位 0
  • 0x20 處:e8 fc ff ff ff → call 0x21,相對偏移 -4(swap 佔位)

5. 重定位後機器碼(ab 反彙編)

ab 反彙編

ab 關鍵指令

  • 0x80480a5:c7 44 24 04 58 91 04 08 → movl $0x8049158, 0x4(%esp),**shared 真實地址**
  • 0x80480b4:e8 07 00 00 00 → call 0x80480c0,**swap 真實入口**

6. 符號真實地址來源

ab 符號表 shared

ab 數據段

  • shared 位於 .data 段起始 0x08049158
  • swap 位於 .text 段內 0x080480c0

7. 重定位計算驗證

項目公式數值結果
shared (R_386_32)S + A0x08049158 + 00x08049158 → 小端 58 91 04 08 ✅
swap (R_386_PC32)S + A - P0x080480c0 + (-4) - 0x080480b50x7 → 小端 07 00 00 00 ✅

核心結論

  1. 靜態鏈接本質:**段合併重定基址 + 符號綁定 + 機器碼回填**
  2. R_386_32 用於數據絕對地址,**直接填最終虛擬地址**
  3. R_386_PC32 用於 call/jmp 相對跳轉,**填相對偏移 (目標 - 下一條指令地址)**
  4. 所有重定位信息編碼在 .rel.text、.rel.data 等重定位表中,鏈接器按表逐項處理

這組圖證鏈,是理解「鏈接器如何把分散的 .o 縫合成連續內存映像」的最直觀教材。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved