三.計算機系統之連接

一.文件解析(鏈接)過程

  • 彙編器將彙編文件xxx.s編譯成可重定位目標文件
    • 目標文件由若干個Section組成,咱們在彙編程序中聲明的.section會成爲目標文件中的Section,此外匯編器還會自動添加一些Section(好比符號表)。
  • 鏈接器將多個可重定位文件翻譯成可執行目標文件
    • 把目標文件中的Section(節)合併成幾個Segment(段)。

TIPS: 例如將swap.o 和main.o 翻譯成可執行文件P: ld -o P swap.o main.o編程

二.目標文件

  • 在編譯過程當中有多種文件,彙編和鏈接部分有三種文件(ELF文件)
      1. 可重定位目標文件: 包涵二進制代碼和數據。其做用:在編譯時與其它可重定位目標文件合併起來,建立一個可執行目標文件。
      • 和可執行文件區別:自包含當前文件的符號解析,而且符號都沒有實際的虛擬地址
      1. 可執行文件: 包含二進制代碼和數據。做用:可用被直接拷貝到存儲器並執行.
      1. 共享目標文件: 一種特殊類型的可重定位目標文件。做用:加載或者運行時唄動態地加載到存儲器並連接。

三.彙編器

  • 這個文件是彙編器編譯單個文件生成的(xxx.o)文件,可重定位目標文件(ELF格式).下面是各section
    • .text: 已編譯程序的機器代碼
    • .rodata: 只讀數據,好比printf語句中的格式串和開關語句的跳轉表
    • .data: 已初始化的全局C變量。局部變保存在棧中.存放具體數據
    • .bss: 未初始化的全局C變量,不佔空間,僅僅是一個佔位符。目標文件格式區分初始化和未初始uabianl是爲了空間效率
    • .symtab: 一個符號表。存放在程序全部符號 ( 函數/變量) 的符號名、section號、地址、約束約束信息:global、local這種限定
    • .rel.text: 鏈接時.text 中須要修改地址的函數
    • .rel.data:鏈接時.data 中須要修改地址的變量
    • debug: 一個調試符號表
    • line: 原始C源程序中的行號和.text節中機器指令之間的映射。
    • .strtab: 一個字符串表

四.連接器

  • 1.連接的做用的過程函數

    • 編譯時:將源代碼翻譯成機器代碼
    • 加載時: 程序被夾在器加載到存儲器並執行
    • 運行時:由程序執行
  • 2.特色翻譯

    • 理解連接將幫助你構造大型程序。
    • 理解鏈接將幫助你避免一些危險的編譯錯誤
    • 理解鏈接將幫助你理解語言的做用域規則是如何實現的。
    • 理解鏈接將幫助你理解語其它重要的系統概念
    • 理解鏈接將使你可以利用共享庫
  • 3.編譯時的做用debug

    • 符號解析: 彙編器生成的是從地址0開始的代碼和數據節,鏈接器將每一個符號引用恰好和一個符號定義聯繫起來。將多個文件的全局變量和函數(默認全局)、static靜態變量和static函數與引用,關聯起來。若是有重複,則經過規則肯定引用的惟一性
    • 重定位:
      • 彙編器:生成的是從地址0開始的代碼和數據節。
      • 鏈接器:把每一個符號與一個存儲器位置聯繫起來,而後修改全部對這些符號的引用,使它們指向這個存儲器的位置,從而重定位這些字節。
        • 就是給全局變量和函數(默認全局)、static靜態變量和static函數分配地址
  • 4.符號和符號表調試

    • 由模塊m (文件m) 定義能被其它模塊引用的全局符號
    • 有其它模塊定義能被模塊m (文件m) 引用的全局符號
    • 只被模塊m (文件m) 定義和引用的本地符號:static 變量(全局/本地)和函數
  • 5.符號解析規則code

    • 將每一個引用與它的定義文件(可重定位目標文件)的符號表中的一個肯定的符號聯繫起來。
      • 就是將引用符號替換成定義的虛擬地址空間中的地址(該地址記錄在定義文件的符號表中)
  • 6.解析全局符號規則ip

    • 不容許多個強符號。直接被初始化值的全局變量,不能同名定義多個
    • 若是有一個強符號和多個弱符號,那麼選強符號
    • 若是有多個弱符號,那麼從這些弱符號中任選一個
    • tips:強符號:被初始化的值的全局變量函數;弱符號
  • 7.與靜態庫鏈接內存

    • gcc main.c /usr/lib/libm.a /usr/lib/libc.a
  • 8.解析靜態庫的引用作用域

    • 三個集合:
      • 1 可重定位目標文件E,會被合併形參可執行文件
      • 2 引用了,可是還沒有定義的符號集合U
      • 3 前面輸入文件已經定義的符號D
    • 規則
      • 先掃描符號到U
      • 將定義了的符號(可能現階段纔剛剛掃描一部分)存放到D,未定義的存放到E
      • 最後合併E中的目標文件,從而構建輸出的可執行文件.
  • 9.可重定位字符串

    • 一旦鏈接器完成了符號解析這一步,它就把每一個符號引用和肯定的一個符號定義聯繫起來了

    • 重定位節和符號定義:鏈接器將全部相同類型的節合併爲同一類型的新的聚合節(段),並運行時的存儲器地址賦給新的聚合節(段)虛擬內存是以頁爲單位加載的,同一頁必須相同的讀寫修改權限,一段能夠多個頁

    • 重定位節中的符號引用:鏈接器修改代碼節和數據節中對每一個符號的引用,將他們指向正確的運行時地址生成可執行目標文件

  • 10.可執行目標文件

    ELF的格式的可執行目標文件,帶有地址的聚合文件,可加載到系統中

相關文章
相關標籤/搜索