在鏈結中,目標檔案之間相互拼合實際上是目標檔案之間對位址的引用,即對函式和變數的位址的引用(reference)。
我們將函式和變數統稱為符號(symbol),函式名或變數名即符號名。
每乙個目標檔案都有乙個相應的符號表,記錄了該目標檔案中用到的所有符號。
每個定義的符號有乙個對應的值,即符號值,對於變數和函式來說,符號值即它們的位址。
型別:(以******section.o為例)
1.定義在本目標檔案的全域性符號,可以被其他目標檔案引用。如"func1"、"main"、"global_init_var"。
2.在本目標檔案中引用的全域性符號,卻沒有定義在本目標檔案,即外部符號(external symbol)。如「printf」。
3.段名,其值為該段的起始位址。
4.區域性符號,這類符號只在編譯單元內部可見。鏈結器往往會忽略它們,因為沒用。
5.行號資訊(可選的)。
檢視符號表
elf符號表往往是檔案中的乙個段「.symtab」,是乙個elf32_sym結構(對應乙個符號)的陣列。
檢視elf檔案的符號
num:表示符號表陣列的下標。
value:符號值。對於函式,是其相對於**段起始位置的偏移量。
size:符號大小。
type:符號型別。
bind:繫結資訊。
vis:暫無。
ndx:表示該符號所屬的段。(可通過readelf -a 或 objdump -x 驗證)
name:符號名稱。
特殊符號
當使用ld作為鏈結器來鏈結生產可執行檔案時,它會為我們定義很多特殊符號,這些符號並沒有在你的程式中定義,但你可以直接宣告並引用它。
這些符號被定義在鏈結指令碼中。鏈結器會在將程式最終鏈結成可執行檔案的時候將其解析成正確的值。
__executable_start 該符號為程式起始位址,是程式的最開始的位址。不是入口位址。
__etext or _etext or etext **段結束位址。
_edata or edata 資料段結束位址。
_end or end 程式結束位址。
以上位址都是程式被裝載時的虛擬位址。
符號修飾與函式簽名預設
extern "c"
c++為了和c相容,c++有乙個用來宣告或定義乙個c的符號的「extern "c"」關鍵字用法:
extern "c"{
int func(int);
int var;預設
除錯資訊
gcc編譯時加「-g」引數在目標檔案中加上除錯資訊
$strip foo去掉elf檔案中的除錯資訊
現在的elf檔案採用dwarf(debug with arbitrary record format)
程式設計師的自我修養 讀書筆記
第一部分 溫故而知新 第一章 介紹基本的背景知識 作業系統 執行緒 硬體 1 關於c語言中的hello world這些問題你都清楚嗎?2 計算機硬體裝置的三個核心部件 1 處理器cpu 2 記憶體 3 i o控制晶元 4 作業系統的功能 1 提供抽象介面。2 管理硬體資源 5 多道程式 分時系統 多...
《程式設計師的自我修養》讀書筆記
1 最佳實踐 作為一名程式設計師,你也需要嘗試去理解那些軟體領域最本質的東西,而我的建議就是學習那些最佳實踐。最佳實踐 bestpractice 是乙個管理學概念,即 可使結果最優,並減少出錯可能性的某種技術或方法。最佳實踐一定是要經受住實踐檢驗才得出的。學習本質 是 以慢打快 的策略,但這種策略短...
程式設計師的自我修養 讀書筆記
哦,笑吧,科廷,老夥計。這是上帝,或者也可以說是命運或自然,跟我們開的乙個玩笑。不過,不管這傢伙是誰或是什麼,他真幽默,哈哈!霍華德,碧血沙金 專業主義不但象徵著榮譽與驕傲,而且明確意味著責任與義務。假如不小心在程式中寫了乙個bug,以致於公司損失10萬,對於非專業人士來說,只會聳聳肩 狀況總是難免...