程式設計師的自我修養 目標檔案

2021-07-10 15:10:42 字數 2394 閱讀 5495

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 裡裝載...