Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2287285
  • 博文数量: 668
  • 博客积分: 10016
  • 博客等级: 上将
  • 技术积分: 8588
  • 用 户 组: 普通用户
  • 注册时间: 2008-05-29 19:22
文章分类

全部博文(668)

文章存档

2011年(1)

2010年(2)

2009年(273)

2008年(392)

分类:

2008-10-13 15:06:49

在「理解 dynamic loader 內部原理的幾個先備知識(一)」講到:.bss 節區「linking view」上不佔檔案空間。這點可以用 readelf 來做 ELF linking view 端的印證:

# readelf -e bss|more  (bss 是我們的範例執行檔)
...
Section Headers:
  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            00000000 000000 000000 00      0   0  0
  [ 1] .interp           PROGBITS        080480f4 0000f4 000013 00   A  0   0  1
  [ 2] .note.ABI-tag     NOTE            08048108 000108 000020 00   A  0   0  4
  [ 3] .hash             HASH            08048128 000128 000028 04   A  4   0  4
  [ 4] .dynsym           DYNSYM          08048150 000150 000050 10   A  5   1  4
  [ 5] .dynstr           STRTAB          080481a0 0001a0 00004c 00   A  0   0  1
  [ 6] .gnu.version      VERSYM          080481ec 0001ec 00000a 02   A  4   0  2
  [ 7] .gnu.version_r    VERNEED         080481f8 0001f8 000020 00   A  5   1  4
  [ 8] .rel.dyn          REL             08048218 000218 000008 08   A  4   0  4
  [ 9] .rel.plt          REL             08048220 000220 000010 08   A  4   b  4
  [10] .init             PROGBITS        08048230 000230 000017 00  AX  0   0  4
  [11] .plt              PROGBITS        08048248 000248 000030 04  AX  0   0  4
  [12] .text             PROGBITS        08048278 000278 0001b8 00  AX  0   0  4
  [13] .fini             PROGBITS        08048430 000430 00001b 00  AX  0   0  4
  [14] .rodata           PROGBITS        0804844c 00044c 000031 00   A  0   0  4
  [15] .eh_frame         PROGBITS        08048480 000480 000004 00   A  0   0  4
  [16] .data             PROGBITS        08049484 000484 00000c 00  WA  0   0  4
  [17] .dynamic          DYNAMIC         08049490 000490 0000c8 08  WA  5   0  4
  [18] .ctors            PROGBITS        08049558 000558 000008 00  WA  0   0  4
  [19] .dtors            PROGBITS        08049560 000560 000008 00  WA  0   0  4
  [20] .jcr              PROGBITS        08049568 000568 000004 00  WA  0   0  4
  [21] .got              PROGBITS        0804956c 00056c 000018 04  WA  0   0  4
  [22] .bss              NOBITS          08049584 000584 00000c 00  WA  0   0  4
  [23] .comment          PROGBITS        00000000 000584 000132 00      0   0  1
...

重點的部份我用粗體字標示出來了:.bss section 與 .comment section 在檔案裡的 offset 是相同的。不過,用「他人」的工具來印可能會有一些盲點存在,比如說,我們可能不是很明白「Off」真正的意義;建議使用我們自行撰寫的 ELF 讀檔程式 loader-0.5.c()來做,因為這是自己寫的工具,能保證一些盲點都能得到證明。以下是用 loader-0.5.c 印出來的畫面:

# ./loader bss
ELF Identification
  Class:        32-bit objects
Machine:        Intel 80386
Name                Size FileOff
[00] .interp               19     244
[01] .note.ABI-tag         32     264
[02] .hash                 40     296
[03] .dynsym               80     336
[04] .dynstr               76     416
[05] .gnu.version          10     492
[06] .gnu.version_r        32     504
[07] .rel.dyn               8     536
[08] .rel.plt              16     544
[09] .init                 23     560
[10] .plt                  48     584
[11] .text                440     632
[12] .fini                 27    1072
[13] .rodata               49    1100
[14] .eh_frame              4    1152
[15] .data                 12    1156
[16] .dynamic             200    1168
[17] .ctors                 8    1368
[18] .dtors                 8    1376
[19] .jcr                   4    1384
[20] .got                  24    1388
[21] .bss                  12    1412
[22] .comment             306    1412

了解 ELF 並自己撰寫工具,此過程讓我們了解到「Offset」指的是「確實是該 section 在檔案裡的啟始讀取位置」。這代表,無論程式裡有多少 uninitialized data,都是不佔用額外的檔案空間的。

畫面中的節區大小

「Size」代表該 section 的實體大小(in bytes),以 .bss section 來說,.bss section 的大小是 12 bytes。很不幸的是,這個大小並非表示 .bss section 佔用的「檔案大小」,而是「記憶體大小」;這可能會是一個使用工具時,因為畫面的「字義」所不小心產生的盲點。所以如果把 .bss section 的 Offset 加上他的 Size,並不會等於 .comment section 的 Offset

所謂的「Size」,包含由 objdump 與 readelf 所列印出來的畫面,或者說,「紀載在 section header entry」裡的 size 資訊,是表示「該 section 的實體記憶體大小」。

.bss section 的長度計算方式

.bss 的大小計算方式為(IA32 平臺):

4 bytes + sizeof(所有的 uninitialized data)

這代表 .bss section 在記憶體所會佔用的長度。以先前的例子來說,計算式會是:

4 + sizeof(foo) + sizeof(bar) = 4 + 4 + 4 = 12 (bytes)

所以,.bss section 的「size」field 就是 12。

.bss section 的結構

.bss section 的空間結構類似於 stack,所以前一則日記講述的「foo 是第一個 uninitialized data,所以他的 virtual address,形同 .bss section 的開始位址(process virtual address)。」觀念,並非全然正確

此部份留待後續再做說明。

阅读(1113) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~