編譯—連結—載入工具鏈

符號表(symbol table)

當你在程式碼裡給函式或全域變數取名時,那個名稱只是給你和編譯器用的;執行中的機器只認數值位址。符號表是目的檔內部那個橋接兩者的小目錄:它列出這個檔案所關注的具名事物(稱為符號),並為每一個記下到目前為止已知的資訊。它是連結器用來弄清楚如何把各別檔案連在一起所讀的索引卡目錄。

每一筆登錄把名稱配上資訊:它位於哪個區段、在該區段內的偏移量、它是函式還是資料物件、它對其他檔案可見(external)或為本檔私有(local,static 會使之如此),以及最關鍵的——它在這裡是被定義還是僅被參照。你的檔案所定義的符號,例如你寫的 add 函式,會得到一筆指向它在 .text 中位置的登錄。你的檔案使用卻未定義的符號,例如 printf,則得到一筆標記為未定義的登錄,是一張寫著「別人必須提供這個」的便條。

符號表是連結的原料。連結器讀取每個目的檔的符號表,把一個檔案中的每個未定義符號與另一個檔案(或函式庫)中的定義符號配對,並寫下最終位址,使該參照得以修補。如果一個名稱被參照卻在任何地方都沒被定義,你會得到「undefined reference」連結錯誤;如果同一個名稱在兩個檔案中被定義,你會得到「multiple definition」。像 nm 這樣的工具會直接印出符號表,用 T 之類的字母代表已定義的 text 符號、U 代表未定義的符號。

$ nm main.o U add # main 用到 add,但沒定義它(未定義) 0000000000000000 T main # main 定義在這裡,於 .text # 連結器必須在其他某個 .o 或函式庫中找到一個 'T add' 才能滿足這個 'U add'

符號表同時記錄一個檔案定義了什麼(T)與它留下未定義的是什麼(U)。

static 函式或變數在符號表中被標為 local,所以對其他檔案不可見;兩個檔案可以各自擁有同名的 static 輔助函式而不衝突。

又称
symtab符號表