ELF檔案資料布局探索 1

2022-08-16 12:24:17 字數 3421 閱讀 8580

作為一名linux小白,第一次看到a.out這個名字,感覺實在是奇怪,搜了一下才知道這是編譯器輸出的預設可執行檔名

順便看到了readelf這條命令,就讀了一下這個檔案,發現這裡邊好多東西都不懂,後來在學習linux的過程中漸漸明白了

一部分,前幾天剛好跟同學說到了關於elf檔案資料布局的問題,今天總結一下(羅嗦了這麼多,真是不好意思)。

今天討論的問題是:我們在源程式中定義的變數是否會被儲存在elf中以及存放在什麼地方。讓我們一步一步往下看:

先丟擲兩個結論:

a. data段的資料儲存在elf檔案中;

b. bss段的資料不儲存在elf檔案中,elf檔案中的bss段只是記錄bss段所需要的大小。

1. 對比**, 下面這段**用於對比測試:

1

intmain( )

測試結果:

du -h a.out 

8.0k a.out

size a.out

text       data        bss        dec        hex    filename

1056        252          8       1316        524    a.out

2. 全域性變數

2.1 未初始化:

1

int a[1024];2

intmain( )

測試結果:

du -h a.out 

8.0k a.out

size a.out

text data bss dec hex filename

1056

2524128

5436 153c a.out

可以看出,bss段的值變為了4128,正好是32 + 4096,為什麼不是8 + 4096,我想應該是bss段是32位元組對齊的,至於初始為什麼沒有對齊,留待大神解釋。

那麼為什麼a.out的大小還是8.0k呢?大家先想一想。

2.2 初始化

1

int a[1024] = ;

2int

main( )

可能有同學要說了,你這只初始化了乙個值嗎?先往下看:

測試結果:

du -h a.out 

12k a.out

size a.out

text data bss dec hex filename

1056

4372

85436 153c a.out

這次bss段值沒變,而資料段多了4372 - 252 = 4120,為什麼不是4096,說明data段應該也是32位元組對齊的。細心的同學肯定發現了,a.out的大小增加

了4k,這說明什麼,說明a[1024]資料被寫入了elf檔案中,也就是說data段中變數的值全部被寫入到了elf檔案中。那現在想一想,為什麼bss段增加了而a.out

沒有增加呢,說明bss段只是記錄了變數佔據儲存空間的大小,並沒有在elf中為變數分配儲存,這裡可以證明上面的兩個結論是正確的。

現在回答一下上面的問題,為什麼我只初始化了乙個值,其實我們知道,陣列是連續存放的,因此,只要初始化了乙個值,其它的資料位址也就確定了。

3. 靜態變數

3.1 未初始化

1

intmain( )

測試結果:

du -h a.out 

8.0k a.out

size a.out

text data bss dec hex filename

1056

2524128

5436 153c a.out

bss段增加了4096 + 對齊位元組,說明未經初始化的靜態變數在bss段。

3.2 初始化

1

intmain( ) ;

3return0;

4 }

測試結果:

du -h a.out 

12k a.out

size a.out

text data bss dec hex filename

1056

4372

85436 153c a.out

data段增加了4096 + 對齊位元組,目標檔案a.out增加了4k,說明經過初始化的靜態變數在data段。

4. 字串常量

1

intmain( )

測試結果:

du -h a.out 

7122    a.out

size a.out

text data bss dec hex filename

1075

2528

1345

541 a.out

1 

intmain( )

測試結果:

du -h a.out 

8.0k a.out

size a.out

text data bss dec hex filename

1085

2528

1345

541 a.out

可以看到只有text段增加了,而且通過設定不同的長度,第二次比第一增加了10b,說明「確實」是被放在text段了。但經過進一步分析,使用readelf命令,發現實際上

"666666666666"的位址在rodata段範圍內,實際上字串常量是被儲存在rodata段中的,size命令看來也是個坑啊!需要指出,rodata段的內容也是要佔據elf檔案

儲存的,並不僅僅只記錄資料大小。

5. 區域性變數

下表是我在linux核心版本3.2.0的測試結果:

變數屬性

是否在elf中

是否儲存在elf中

段未經初始化的全域性變數是否

bss段

經過初始化的全域性變數是是

data段

未經初始化的靜態變數是否

bss段

經過初始化的靜態變數是是

data段

字串常量是是

rodata段

巨集定義常量是是

rodata段

區域性變數否否

VC讀取TXT檔案資料(1)

一 運用cstdiofile readstring cstdiofile f your file name cstring str while f.readstring str 二 程式實現 假設你已有了名為ts.txt的檔案在你的工程目錄下 o file.getposition 記錄上次的結果 讀...

VC讀取TXT檔案資料(1)

一 運用cstdiofile readstring cstdiofile f your file name cstring str while f.readstring str 二 程式實現 假設你已有了名為ts.txt的檔案在你的工程目錄下 o file.getposition 記錄上次的結果 讀...

檔案資料組織

資料庫的基本概念 二 曾士熊 原文 http www.ascc.sinica.edu.tw nl 83 1009 section3 3.html 劉建文整理 http blog.csdn.net keminlau 本文接第10個卷08期68頁 常見的電腦檔案包括 可執行程式檔案,批處理檔案,文字檔案...