程式的連結和裝入及Linux下動態連結的實現
https://www.ibm.com/developerworks/cn/linux/l-dynlink/
簡介: 程式的連結和裝入存在著多種方法,而如今最為流行的當屬動態連結、動態裝入方法。本文首先回顧了連結器和裝入器的基本工作原理及這一技術的發展歷史,然後通過實際的例子剖析了Linux系統下動態連結的實現。瞭解底層關鍵技術的實現細節對系統分析和設計人員無疑是必須的,尤其當我們在面對實時系統,需要對程式執行時的時空效率有著精確的度量和把握時,這種知識更顯重要。
一個程式要想在記憶體中執行,除了編譯之外還要經過連結和裝入這兩個步驟。從程式設計師的角度來看,引入這兩個步驟帶來的好處就是可以直接在程式中使用printf和errno這種有意義的函式名和變數名,而不用明確指明printf和errno在標準C庫中的地址。當然,為了將程式設計師從早期直接使用地址程式設計的夢魘中解救出來,編譯器和彙編器在這當中做出了革命性的貢獻。編譯器和彙編器的出現使得程式設計師可以在程式中使用更具意義的符號來為函式和變數命名,這樣使得程式在正確性和可讀性等方面都得到了極大的提高。但是隨著C語言這種支援分別編譯的程式設計語言的流行,一個完整的程式往往被分割為若干個獨立的部分並行開發,而各個模組間通過函式介面或全域性變數進行通訊。這就帶來了一個問題,編譯器只能在一個模組內部完成符號名到地址的轉換工作,不同模組間的符號解析由誰來做呢?比如前面所舉的例子,呼叫printf的使用者程式和實現了printf的標準C庫顯然就是兩個不同的模組。實際上,這個工作是由連結器來完成的。
為了解決不同模組間的連結問題,連結器主要有兩個工作要做――符號解析和重定位:
符號解析:當一個模組使用了在該模組中沒有定義過的函式或全域性變數時,編譯器生成的符號表會標記出所有這樣的函式或全域性變數,而連結器的責任就是要到別的模組中去查詢它們的定義,如果沒有找到合適的定義或者找到的合適的定義不唯一,符號解析都無法正常完成。
重定位:編譯器在編譯生成目標檔案時,通常都使用從零開始的相對地址。然而,在連結過程中,連結器將從一個指定的地址開始,根據輸入的目標檔案的順序以段為單位將它們一個接一個的拼裝起來。除了目標檔案的拼裝之外,在重定位的過程中還完成了兩個任務:一是生成最終的符號表;二是對程式碼段中的某些位置進行修改,所有需要修改的位置都由編譯器生成的重定位表指出。
可執行程式生成後,下一步就是將其裝入記憶體執行。Linux下的編譯器(C語言)是cc1,彙編器是as,連結器是ld,但是並沒有一個實際的程式對應裝入器這個概念。實際上,將可執行程式裝入記憶體執行的功能是由execve(2)這一系統呼叫實現的。簡單來講,程式的裝入主要包含以下幾個步驟:
- 讀入可執行檔案的頭部資訊以確定其檔案格式及地址空間的大小;
- 以段的形式劃分地址空間;
- 將可執行程式讀入地址空間中的各個段,建立虛實地址間的對映關係;
- 將bbs段清零;
- 建立堆疊段;
- 建立程式引數、環境變數等程式執行過程中所需的資訊;
- 啟動執行。
相關文章
- Linux環境下:程式的連結, 裝載和庫[靜態連結]Linux
- linux下靜態連結庫和動態連結庫的區別有哪些Linux
- 靜態連結動態連結的連結順序問題和makefile示例
- 動態連結的步驟與實現
- cmake 連結動態連結庫
- 動態連結串列的建立(程式碼)
- Linux軟連結和硬連結Linux
- linux硬連結和軟連結Linux
- 動態連結庫與靜態連結庫
- 動態連結的相關結構
- 動態連結庫的生成和使用(二)
- 動態連結庫(DLL)的建立和使用
- Linux環境下:程式的連結, 裝載和庫[ELF檔案詳解]Linux
- Linux(8) —— 硬連結和軟連結Linux
- Linux 軟連結和硬連結簡介Linux
- 簡談linux中軟連結和硬連結的區別Linux
- 使用js動態新增連結隨機連結JS隨機
- 動態連結的PLT與GOTGo
- 關於顯示載入動態連結庫模組及解除安裝的問題
- 連結串列-單連結串列實現
- 【連結 1】與靜態連結庫連結
- 載入動態連結庫——dlopen dlsym dlclose
- 關於動態連結串列的理解
- “軟連結”和“硬連結”的區別
- 硬連結和軟連結的區別
- Windows環境下,動態連結庫(DLL)的“匯入”與“匯出”概念Windows
- Java連結c++動態庫實現字串的傳輸---簡單的字元拼裝返回JavaC++字串字元
- 線上生成短連結的原因及實現工具
- 【技術向】Linux動態連結庫預載入型後門Linux
- Linux硬連結和軟連線有哪些知識點?Linux入門Linux
- 『學了就忘』Linux基礎命令 — 22、Linux中的硬連結和軟連結Linux
- 在Linux中,什麼是硬連結和軟連結?Linux
- PHP獲取動態跳轉後的真實連結PHP
- pta重排連結串列(一個很清晰的實現,完全模擬連結串列的實現)
- 硬連結和軟連結
- 微信域名連結防封短連結是如何生成的,微信域名防封短連結程式碼實現示例
- JNI呼叫c動態連結庫函式程式碼實踐函式
- 《程式設計師的自我修養》筆記(二)——裝載與動態連結程式設計師筆記
- 在 Linux中如何使用動態連結模組庫?Linux