1.「檔案頭」:描述整個檔案的檔案的檔案屬性,包括檔案是否可執 行、是靜態鏈結還是動態鏈結及入口位址(可執行檔案)、目標硬體、目標作業系統等資訊,檔案頭還包括乙個段表。段表其實就是乙個描述檔案中各個段的陣列,描述段在檔案中的偏移位置及段的屬性等。
2..text段:編譯後執行語句都編譯成機器**,儲存在該段。
3..data段:已經初始化的全域性變數和區域性靜態變數都儲存在該段。
4..bass段:未初始化的全域性變數和區域性靜態變數一般放在該段。
總體來說,程式源**被編譯之後主要分成兩種段:程式指令和程式資料。**段屬於程式指令,而資料段和.bss段屬於程式資料。
.rodata段:存放的是唯讀資料,一般是程式裡面的唯讀變數和字串變數。
以「.」 字首的段是系統保留的,程式可以室友一些非系統保留的段名建立新段。
__attribute__((section("name"))) int val = 21;
//gcc的擴充套件機制,指定變數所處的段
初始化為0或未初始化的變數會被編譯器優化放在.bss段(不佔磁碟空間),這樣可節省磁碟空間。
許可權:資料區域對程序來說是可讀寫的,指令區域對於程序來說是唯讀的。程式被裝載後,資料和指令分別被對映到兩個虛存區域,許可權可以分別被設定為可讀寫和唯讀。防止程式的指令被有意或無意修改。
指令區和資料區分離有利於提高程式的區域性性。對cpu的快取命中率提高有好處。
最重要的原因。系統中執行多個該程式的副本時,他們的指令都是一樣的,所以記憶體中只要儲存乙份改程式的指令部分(共享指令)。對於唯讀指令來說是這樣,對於其他唯讀資料也是一樣。共享指令在現代作業系統中占有極為重要的地位,特別是在有動態鏈結庫的系統中,可以節省大量記憶體。
-h:把elf 檔案的各個段的基本資訊列印出來。
-x:列印更多資訊。
size命令:可以檢視elf檔案的**段、資料段和bss 段的長度。
-s:所有段的內容以十六進製制列印出來。
-d:反彙編所有包含指令的段。
每個定義的符號有乙個定義的值(符號值),就是變數和函式的位址。
符號分類:
1. 定義子在本目標檔案的全域性符號,可被其他目標檔案引用。
2. 在本目標檔案引用的全域性符號,卻沒有定義在本目標檔案。(外部符號)
3. 段名:一般由編譯器產生,值為該段起始位址。
4. 區域性符合,只在編譯單元內部可見。
5. 行號資訊,目標檔案指令與源**中**行的對應關係,可選。
6. 特殊符號:沒有在程式中定義,但可以直接宣告並且引用它。
1). __executable_start,程式最開始的位址(不是入口位址)。
2). __etext 或 _etext 或 etext ,**最末尾位址。
3). _edata 或 edata ,資料段最末尾位址。
4). _end 或 end ,程式結束位址。
c++ 編譯器會將在extern 「c」的大括號內的**當作c語言**處理,c++的名稱修飾機制將不會起作用。
c++的巨集「__cplusplus」:c++編譯器在編譯c++程式時預設定義該巨集,可以使用該條件巨集判斷當前編譯單元是不是c++**。
c/c++語言,編譯器預設將函式和初始化了的全域性變數作為強符號,未初始化的全域性變數作為弱符號。(可用 gcc 的 「__attribute__((weak))
「定義任何乙個強符號為弱符號)
鏈結器對於全域性符號處理規則:
1. 不允許強符號多次定義,否則會報錯。
2. 如果乙個符號在某個目標檔案中是強符號,其他檔案都是弱符號,選擇強符號。
3. 所有目標檔案中都是弱符號,選擇占用空間最大乙個。
正是由於第三條,所以編譯時弱符號所需空間大小是未知的,編譯器無法為某一弱符號分配空間。但鏈結器在鏈結過程中可以確定弱符號大小。
在鏈結成最終可執行檔案時,需正確決議,若沒能找到該符號定義,鏈結器報符號未定義錯誤,稱為強引用。
弱引用,如果符號未定義,鏈結器不抱錯。未定義的弱引用,鏈結器一般預設為0。(__attribute__((weakref))
宣告外部函式引用為弱引用)
庫中定義的弱符號可以被使用者定義的強符號覆蓋,從而使得程式可以使用自定義版本的庫函式;
程式可以對某些擴充套件功能模組的引用定義為弱引用,當我們將擴充套件模組與程式鏈結在一起時,功能模組就可以正常使用;若去掉也可以正常鏈結,只是少了某些功能,是程式功能更加容易裁剪和組合。
學習程式設計師的自我修養之目標檔案
目標檔案中包含了編譯後的機器指令 資料和連線時所需的資訊,如符號表 除錯資訊 字串等。一般情況下,目標檔案都將這些資訊按不同的屬性,以節 section 或段 segment 的形式進行儲存。程式源 編譯後的機器指令經常被放在 段 code section 中,段的常見名有.code或.text。定...
程式設計師的自我修養 3 目標檔案有什麼》
目標檔案的型別 可重定位檔案,可執行檔案,共享目標檔案,核心轉儲檔案。test 儲存的就是程式的 部分,除了資料段,bss段,堆疊段等一般是存放在 段中。data 儲存的是那些已經初始化了的全域性靜態變數和區域性靜態變數。rodata段存放的是唯讀資料,一般是程式裡面的唯讀變數 如const修飾的變...
程式設計師的自我修養 目標檔案裡有什麼
這一章主要講述目標檔案有哪幾個部分組成以及介紹組成部分。elf格式檔案有檔案頭和各個段組成。2.段 section sections 是在elf檔案裡頭,用以裝載內容資料的最小容器。在elf檔案裡面,每乙個 sections 內都裝載了性質屬性都一樣的內容。例如 1 text section 裡裝載...