阿龍的學習筆記---《程式設計師自我修養-連結、裝載與庫》讀書筆記(二)

阿龍-發表於2020-10-23

四、靜態連結

  • 首先放一個例子,從這裡來看靜態連結到底做什麼。
    在這裡插入圖片描述

  • 1. 空間與地址的分配

    • 首先,對於兩個目標檔案,肯定要合併到一起,各個段合併在一起。一般連結器都會將不同目標檔案的相同段放在一起。
    • 空間與地址的分配: 掃描輸入目標檔案,並且獲得它們的各個段的長度、屬性和位置,把不同符號表中的符號統一放到全域性符號表。這一步中,連結器將能夠獲得所有輸入目標檔案的段長度,並且將它檔案中各個段合併後的長度與位置,並建立對映關係。
    • 在完成這些之後,連結器計算符號的地址(虛擬地址),因為地址分配完成了,各個符號在各個段內的位置固定了。
  • 2.符號解析與重定位

    • 符號解析與重定位:使用上面第一步中收集到的所有資訊,讀取輸入檔案中段的資料、重定位資訊,並且進行符號解析與重定位、調整程式碼中的地址等。事實上第二步是連結過程的核心,特別是重定位過程。
    • 來看上面的圖片例子,在編譯完成後,shared和swap()的地址在彙編程式碼中,都還是無意義的,需要將正確的替換,連結器會替換為剛才分配的正確地址。
    • 連結器如何知道哪些指令和變數需要被調整?從重定位表獲取。也叫重定位段。比如.text段中需要重定位的入口會儲存在.rel.text中
    • 符號解析:當找到重定位入口的符號時,我需要知道這個符號在哪,目標地址是多少。(假如連結時少了哪個庫,則會報錯“連結時符號未定義”。) 這時會去找全域性符號表,找到後進行重定位。
    • 對於強符號、弱符號的解析問題,不展開了,有需要可以再搜一下,採用了COMMOM塊的方法來解決。
  • 靜態庫連結

    • 比如說Linux作業系統的一些輸入輸出就是系統API。LinuxC語言今天庫libc。**靜態庫可以看做一堆目標檔案的集合。**比如libc.a裡面會有printf.o、stdio.o等。
  • 連結過程可以通過ld連結指令碼來控制,具體百度。


相關文章