ELF(Executable and Linking Format)格式教學文件, #8: loader v0.5 與結果輸出(改善與小討論)

jollen 發表於 December 6, 2006 1:12 AM

我們接續 loader v0.4 的工作,強化一下輸出結果的可讀性;先來比較一下 loader v0.4 與 loader v0.5 的輸出畫面。

$ ./loader-0.4 loader-0.4 $ ./loader-0.5 loader-0.4
ELF Identification
  Class:	32-bit objects
Machine:	Intel 80386
Num of secionts: 34
.interp
.note.ABI-tag
.hash
.dynsym
.dynstr
.gnu.version
.gnu.version_r
.rel.dyn
.rel.plt
.init
.plt
.text
.fini
.rodata
.eh_frame
.data
.dynamic
.ctors
.dtors
.jcr
.got
.bss
.comment
.debug_aranges
.debug_pubnames
.debug_info
.debug_abbrev
.debug_line
.debug_frame
.debug_str
.shstrtab
.symtab
.strtab
ELF Identification
  Class:	32-bit objects
Machine:	Intel 80386
Name                Size FileOff
[01] .interp               19     244
[02] .note.ABI-tag         32     264
[03] .hash                 56     296
[04] .dynsym              144     352
[05] .dynstr               98     496
[06] .gnu.version          18     594
[07] .gnu.version_r        32     612
[08] .rel.dyn               8     644
[09] .rel.plt              48     652
[10] .init                 23     700
[11] .plt                 112     724
[12] .text               1292     836
[13] .fini                 27    2128
[14] .rodata              348    2156
[15] .eh_frame              4    2504
[16] .data                 12    2508
[17] .dynamic             200    2520
[18] .ctors                 8    2720
[19] .dtors                 8    2728
[20] .jcr                   4    2736
[21] .got                  40    2740
[22] .bss                   4    2780
[23] .comment             306    2780
[24] .debug_aranges       120    3088
[25] .debug_pubnames       37    3208
[26] .debug_info         2692    3245
[27] .debug_abbrev        312    5937
[28] .debug_line          636    6249
[29] .debug_frame          20    6888
[30] .debug_str          1722    6908
[31] .shstrtab            299    8630
[32] .symtab             1856   10292
[33] .strtab             1132   12148

Cool!做出了 'objdump -x' 的部份功能。頗為有趣,那麼用 objdump 來互相比較一下看看。

loader v0.5 v.s. objdump v.s. readelf

$ objdump -x loader-0.4(只擷取 section 輸出結果) $ ./loader-0.5 loader-0.4
Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .interp       00000013  080480f4  080480f4  000000f4  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  1 .note.ABI-tag 00000020  08048108  08048108  00000108  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  2 .hash         00000038  08048128  08048128  00000128  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  3 .dynsym       00000090  08048160  08048160  00000160  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  4 .dynstr       00000062  080481f0  080481f0  000001f0  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  5 .gnu.version  00000012  08048252  08048252  00000252  2**1
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  6 .gnu.version_r 00000020  08048264  08048264  00000264  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  7 .rel.dyn      00000008  08048284  08048284  00000284  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  8 .rel.plt      00000030  0804828c  0804828c  0000028c  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  9 .init         00000017  080482bc  080482bc  000002bc  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 10 .plt          00000070  080482d4  080482d4  000002d4  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 11 .text         0000050c  08048344  08048344  00000344  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 12 .fini         0000001b  08048850  08048850  00000850  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 13 .rodata       0000015c  0804886c  0804886c  0000086c  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
 14 .eh_frame     00000004  080489c8  080489c8  000009c8  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
 15 .data         0000000c  080499cc  080499cc  000009cc  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 16 .dynamic      000000c8  080499d8  080499d8  000009d8  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 17 .ctors        00000008  08049aa0  08049aa0  00000aa0  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 18 .dtors        00000008  08049aa8  08049aa8  00000aa8  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 19 .jcr          00000004  08049ab0  08049ab0  00000ab0  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 20 .got          00000028  08049ab4  08049ab4  00000ab4  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 21 .bss          00000004  08049adc  08049adc  00000adc  2**2
                  ALLOC
 22 .comment      00000132  00000000  00000000  00000adc  2**0
                  CONTENTS, READONLY
 23 .debug_aranges 00000078  00000000  00000000  00000c10  2**3
                  CONTENTS, READONLY, DEBUGGING
 24 .debug_pubnames 00000025  00000000  00000000  00000c88  2**0
                  CONTENTS, READONLY, DEBUGGING
 25 .debug_info   00000a84  00000000  00000000  00000cad  2**0
                  CONTENTS, READONLY, DEBUGGING
 26 .debug_abbrev 00000138  00000000  00000000  00001731  2**0
                  CONTENTS, READONLY, DEBUGGING
 27 .debug_line   0000027c  00000000  00000000  00001869  2**0
                  CONTENTS, READONLY, DEBUGGING
 28 .debug_frame  00000014  00000000  00000000  00001ae8  2**2
                  CONTENTS, READONLY, DEBUGGING
 29 .debug_str    000006ba  00000000  00000000  00001afc  2**0
                  CONTENTS, READONLY, DEBUGGING
ELF Identification
  Class:	32-bit objects
Machine:	Intel 80386
Name                Size FileOff
[00] .interp               19     244
[01] .note.ABI-tag         32     264
[02] .hash                 56     296
[03] .dynsym              144     352
[04] .dynstr               98     496
[05] .gnu.version          18     594
[06] .gnu.version_r        32     612
[07] .rel.dyn               8     644
[08] .rel.plt              48     652
[09] .init                 23     700
[10] .plt                 112     724
[11] .text               1292     836
[12] .fini                 27    2128
[13] .rodata              348    2156
[14] .eh_frame              4    2504
[15] .data                 12    2508
[16] .dynamic             200    2520
[17] .ctors                 8    2720
[18] .dtors                 8    2728
[19] .jcr                   4    2736
[20] .got                  40    2740
[21] .bss                   4    2780
[22] .comment             306    2780
[23] .debug_aranges       120    3088
[24] .debug_pubnames       37    3208
[25] .debug_info         2692    3245
[26] .debug_abbrev        312    5937
[27] .debug_line          636    6249
[28] .debug_frame          20    6888
[29] .debug_str          1722    6908
[30] .shstrtab            299    8630
[31] .symtab             1856   10292
[32] .strtab             1132   12148

不過事情好像有點怪異,我們的 loader v0.5 怎麼在最後多出 3 個 section 呢?被附身了。

不過,原來是 objdump 不會把最後這 3 個 section 印出來啦,這 3 個 section 分別是:

1) .shstrtab:section header straing table

2) .symtab:symbol table

3) .strtab:string table

哇塞!原來 symbol table 藏在這裡啊。但是,如果我們改用 readelf 來讀 ELF,就可以看到完整的 ELF headers 了,而且輸出的畫面也比較具可讀性:

$ readelf -S loader-0.4

There are 34 section headers, starting at offset 0x22e4:

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 000038 04   A  4   0  4
  [ 4] .dynsym           DYNSYM          08048160 000160 000090 10   A  5   1  4
  [ 5] .dynstr           STRTAB          080481f0 0001f0 000062 00   A  0   0  1
  [ 6] .gnu.version      VERSYM          08048252 000252 000012 02   A  4   0  2
  [ 7] .gnu.version_r    VERNEED         08048264 000264 000020 00   A  5   1  4
  [ 8] .rel.dyn          REL             08048284 000284 000008 08   A  4   0  4
  [ 9] .rel.plt          REL             0804828c 00028c 000030 08   A  4   b  4
  [10] .init             PROGBITS        080482bc 0002bc 000017 00  AX  0   0  4
  [11] .plt              PROGBITS        080482d4 0002d4 000070 04  AX  0   0  4
  [12] .text             PROGBITS        08048344 000344 00050c 00  AX  0   0  4
  [13] .fini             PROGBITS        08048850 000850 00001b 00  AX  0   0  4
  [14] .rodata           PROGBITS        0804886c 00086c 00015c 00   A  0   0  4
  [15] .eh_frame         PROGBITS        080489c8 0009c8 000004 00   A  0   0  4
  [16] .data             PROGBITS        080499cc 0009cc 00000c 00  WA  0   0  4
  [17] .dynamic          DYNAMIC         080499d8 0009d8 0000c8 08  WA  5   0  4
  [18] .ctors            PROGBITS        08049aa0 000aa0 000008 00  WA  0   0  4
  [19] .dtors            PROGBITS        08049aa8 000aa8 000008 00  WA  0   0  4
  [20] .jcr              PROGBITS        08049ab0 000ab0 000004 00  WA  0   0  4
  [21] .got              PROGBITS        08049ab4 000ab4 000028 04  WA  0   0  4
  [22] .bss              NOBITS          08049adc 000adc 000004 00  WA  0   0  4
  [23] .comment          PROGBITS        00000000 000adc 000132 00      0   0  1
  [24] .debug_aranges    PROGBITS        00000000 000c10 000078 00      0   0  8
  [25] .debug_pubnames   PROGBITS        00000000 000c88 000025 00      0   0  1
  [26] .debug_info       PROGBITS        00000000 000cad 000a84 00      0   0  1
  [27] .debug_abbrev     PROGBITS        00000000 001731 000138 00      0   0  1
  [28] .debug_line       PROGBITS        00000000 001869 00027c 00      0   0  1
  [29] .debug_frame      PROGBITS        00000000 001ae8 000014 00      0   0  4
  [30] .debug_str        PROGBITS        00000000 001afc 0006ba 01  MS  0   0  1
  [31] .shstrtab         STRTAB          00000000 0021b6 00012b 00      0   0  1
  [32] .symtab           SYMTAB          00000000 002834 000740 10     33  54  4
  [33] .strtab           STRTAB          00000000 002f74 00046c 00      0   0  1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings)
  I (info), L (link order), G (group), x (unknown)
  O (extra OS processing required) o (OS specific), p (processor specific)

原來這是工具的問題。嗯!好吧,以後都改用 readelf 來玩吧。

Index 0: undefined

還有一點就是,ELF headers index 0 在 SysV ABI 裡的定義是「undefined」,readelf 把它輸出成 NULL,我們的範例跟 objdump 一樣,直接跳過!

readelf 輸出的其它 column 分述如下。

Type

「type」欄位的話就是在「ELF(Executable and Linking Format)格式教學文件, #7: 讀 ELF 的 Section Name(透過 strtab)」裡介紹到的 sh_type

Addr

這個好玩,不過目前先跳過。(>_<)

Off、Size

跟我們的 loader v0.5 輸出結果一樣,分別代表 section 在 ELF object 裡的 file offset 與其大小(bytes)。readelf 是用十六進位輸出,我們的範例是用十進位輸出。

範例程式一樣可以由「http://tw.jollen.org/elf-programming/」下載。

Also See

Jollen's Blog 使用 Github issues 與讀者交流討論。請點擊上方的文章專屬 issue,或 open a new issue

您可透過電子郵件 jollen@jollen.org,或是 Linkedin 與我連絡。更歡迎使用微信,請搜尋 WeChat ID:jollentw