#include <stdio.h> int main(void) { printf("Hello World!\n"); return 0; } |
編譯
cc hw.c |
匯編輸出
cc -S hw.c |
這個命令生成了一個新的文件 hw.s,其中包含您通常無法看到的匯編輸入文本,因為編譯器在缺省情況下將生成 a.out 文件。正如所預期的,UNIX 匯編程序可以對這種輸入文件進行匯編,以生成 a.out 文件。
nm a.out
08049f20 d _DYNAMIC 08049ff4 d _GLOBAL_OFFSET_TABLE_ 080484bc R _IO_stdin_used w _Jv_RegisterClasses 08049f10 d __CTOR_END__ 08049f0c d __CTOR_LIST__ 08049f18 D __DTOR_END__ 08049f14 d __DTOR_LIST__ 080484d0 r __FRAME_END__ 08049f1c d __JCR_END__ 08049f1c d __JCR_LIST__ 0804a014 A __bss_start 0804a00c D __data_start 08048470 t __do_global_ctors_aux 08048360 t __do_global_dtors_aux 0804a010 D __dso_handle w __gmon_start__ 0804846a T __i686.get_pc_thunk.bx 08049f0c d __init_array_end 08049f0c d __init_array_start 08048400 T __libc_csu_fini 08048410 T __libc_csu_init U __libc_start_main@@GLIBC_2.0 0804a014 A _edata 0804a01c A _end 0804849c T _fini 080484b8 R _fp_hw 080482b8 T _init 08048330 T _start 0804a014 b completed.7021 0804a00c W data_start 0804a018 b dtor_idx.7023 080483c0 t frame_dummy 080483e4 T main U puts@@GLIBC_2.0
這些包含可執行代碼的段稱為正文段。同樣地,數據段包含了不可執行的信息或數據。另一種類型的段,稱為 BSS 段,它包含以符號數據開頭的塊。
對於 nm
命令列出的每個符號,它們的值使用十六進制來表示(缺省行為),並且在該符號前面加上了一個表示符號類型的編碼字符。常見的各種編碼包括:A 表示絕對 (absolute),這意味着不能將該值更改為其他的連接;B 表示 BSS 段中的符號;而 C 表示引用未初始化的數據的一般符號。詳解下表
符號 類型 |
說明 |
A | 該符號的值是絕對的,在以后的鏈接過程中,不允許進行改變。這樣的符號值,常常出現在中斷向量表中,例如用符號來表示各個中斷向量函數在中斷向量表中的位置。 |
B | 該符號的值出現在非初始化數據段(bss)中。例如,在一個文件中定義全局static int test。則該符號test的類型為b,位於bss section中。其值表示該符號在bss段中的偏移。一般而言,bss段分配於RAM中 |
C | 該符號為common。common symbol是未初始話數據段。該符號沒有包含於一個普通section中。只有在鏈接過程中才進行分配。符號的值表示該符號需要的字節數。例如在一個c文件中,定義int test,並且該符號在別的地方會被引用,則該符號類型即為C。否則其類型為B。 |
D | 該符號位於初始話數據段中。一般來說,分配到data section中。例如定義全局int baud_table[5] = {9600, 19200, 38400, 57600, 115200},則會分配於初始化數據段中。 |
G | 該符號也位於初始化數據段中。主要用於small object提高訪問small data object的一種方式。 |
I | 該符號是對另一個符號的間接引用。 |
N | 該符號是一個debugging符號。 |
R | 該符號位於只讀數據區。例如定義全局const int test[] = {123, 123};則test就是一個只讀數據區的符號。注意在cygwin下如果使用gcc直接編譯成MZ格式時,源文件中的test對應_test,並且其符號類型為D,即初始化數據段中。但是如果使用m6812-elf-gcc這樣的交叉編譯工具,源文件中的test對應目標文件的test,即沒有添加下划線,並且其符號類型為R。一般而言,位於rodata section。值得注意的是,如果在一個函數中定義const char *test = “abc”, const char test_int = 3。使用nm都不會得到符號信息,但是字符串“abc”分配於只讀存儲器中,test在rodata section中,大小為4。 |
S | 符號位於非初始化數據區,用於small object。 |
T | 該符號位於代碼區text section。 |
U | 該符號在當前文件中是未定義的,即該符號的定義在別的文件中。例如,當前文件調用另一個文件中定義的函數,在這個被調用的函數在當前就是未定義的;但是在定義它的文件中類型是T。但是對於全局變量來說,在定義它的文件中,其符號類型為C,在使用它的文件中,其類型為U。 |
V | 該符號是一個weak object。 |
W | The symbol is a weak symbol that has not been specifically tagged as a weak object symbol. |
- | 該符號是a.out格式文件中的stabs symbol。 |
? | 該符號類型沒有定義 |
完
objdump -d ./a.out ./a.out: file format elf32-i386 Disassembly of section .init: 080482b8 <_init>: 80482b8: 55 push %ebp 80482b9: 89 e5 mov %esp,%ebp 80482bb: 53 push %ebx 80482bc: 83 ec 04 sub $0x4,%esp 80482bf: e8 00 00 00 00 call 80482c4 <_init+0xc> 80482c4: 5b pop %ebx 80482c5: 81 c3 30 1d 00 00 add $0x1d30,%ebx 80482cb: 8b 93 fc ff ff ff mov -0x4(%ebx),%edx 80482d1: 85 d2 test %edx,%edx 80482d3: 74 05 je 80482da <_init+0x22> 80482d5: e8 1e 00 00 00 call 80482f8 <__gmon_start__@plt> 80482da: e8 e1 00 00 00 call 80483c0 <frame_dummy> 80482df: e8 8c 01 00 00 call 8048470 <__do_global_ctors_aux> 80482e4: 58 pop %eax 80482e5: 5b pop %ebx 80482e6: c9 leave 80482e7: c3 ret Disassembly of section .plt: 080482e8 <__gmon_start__@plt-0x10>: 80482e8: ff 35 f8 9f 04 08 pushl 0x8049ff8 80482ee: ff 25 fc 9f 04 08 jmp *0x8049ffc 80482f4: 00 00 add %al,(%eax) ... 080482f8 <__gmon_start__@plt>: 80482f8: ff 25 00 a0 04 08 jmp *0x804a000 80482fe: 68 00 00 00 00 push $0x0 8048303: e9 e0 ff ff ff jmp 80482e8 <_init+0x30> 08048308 <__libc_start_main@plt>: 8048308: ff 25 04 a0 04 08 jmp *0x804a004 804830e: 68 08 00 00 00 push $0x8 8048313: e9 d0 ff ff ff jmp 80482e8 <_init+0x30> 08048318 <puts@plt>: 8048318: ff 25 08 a0 04 08 jmp *0x804a008 804831e: 68 10 00 00 00 push $0x10 8048323: e9 c0 ff ff ff jmp 80482e8 <_init+0x30> Disassembly of section .text: 08048330 <_start>: 8048330: 31 ed xor %ebp,%ebp 8048332: 5e pop %esi 8048333: 89 e1 mov %esp,%ecx 8048335: 83 e4 f0 and $0xfffffff0,%esp 8048338: 50 push %eax 8048339: 54 push %esp 804833a: 52 push %edx 804833b: 68 00 84 04 08 push $0x8048400 8048340: 68 10 84 04 08 push $0x8048410 8048345: 51 push %ecx 8048346: 56 push %esi 8048347: 68 e4 83 04 08 push $0x80483e4 804834c: e8 b7 ff ff ff call 8048308 <__libc_start_main@plt> 8048351: f4 hlt 8048352: 90 nop 8048353: 90 nop 8048354: 90 nop 8048355: 90 nop 8048356: 90 nop 8048357: 90 nop 8048358: 90 nop 8048359: 90 nop 804835a: 90 nop 804835b: 90 nop 804835c: 90 nop 804835d: 90 nop 804835e: 90 nop 804835f: 90 nop 08048360 <__do_global_dtors_aux>: 8048360: 55 push %ebp 8048361: 89 e5 mov %esp,%ebp 8048363: 53 push %ebx 8048364: 83 ec 04 sub $0x4,%esp 8048367: 80 3d 14 a0 04 08 00 cmpb $0x0,0x804a014 804836e: 75 3f jne 80483af <__do_global_dtors_aux+0x4f> 8048370: a1 18 a0 04 08 mov 0x804a018,%eax 8048375: bb 18 9f 04 08 mov $0x8049f18,%ebx 804837a: 81 eb 14 9f 04 08 sub $0x8049f14,%ebx 8048380: c1 fb 02 sar $0x2,%ebx 8048383: 83 eb 01 sub $0x1,%ebx 8048386: 39 d8 cmp %ebx,%eax 8048388: 73 1e jae 80483a8 <__do_global_dtors_aux+0x48> 804838a: 8d b6 00 00 00 00 lea 0x0(%esi),%esi 8048390: 83 c0 01 add $0x1,%eax 8048393: a3 18 a0 04 08 mov %eax,0x804a018 8048398: ff 14 85 14 9f 04 08 call *0x8049f14(,%eax,4) 804839f: a1 18 a0 04 08 mov 0x804a018,%eax 80483a4: 39 d8 cmp %ebx,%eax 80483a6: 72 e8 jb 8048390 <__do_global_dtors_aux+0x30> 80483a8: c6 05 14 a0 04 08 01 movb $0x1,0x804a014 80483af: 83 c4 04 add $0x4,%esp 80483b2: 5b pop %ebx 80483b3: 5d pop %ebp 80483b4: c3 ret 80483b5: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi 80483b9: 8d bc 27 00 00 00 00 lea 0x0(%edi,%eiz,1),%edi 080483c0 <frame_dummy>: 80483c0: 55 push %ebp 80483c1: 89 e5 mov %esp,%ebp 80483c3: 83 ec 18 sub $0x18,%esp 80483c6: a1 1c 9f 04 08 mov 0x8049f1c,%eax 80483cb: 85 c0 test %eax,%eax 80483cd: 74 12 je 80483e1 <frame_dummy+0x21> 80483cf: b8 00 00 00 00 mov $0x0,%eax 80483d4: 85 c0 test %eax,%eax 80483d6: 74 09 je 80483e1 <frame_dummy+0x21> 80483d8: c7 04 24 1c 9f 04 08 movl $0x8049f1c,(%esp) 80483df: ff d0 call *%eax 80483e1: c9 leave 80483e2: c3 ret 80483e3: 90 nop 080483e4 <main>: 80483e4: 55 push %ebp 80483e5: 89 e5 mov %esp,%ebp 80483e7: 83 e4 f0 and $0xfffffff0,%esp 80483ea: 83 ec 10 sub $0x10,%esp 80483ed: c7 04 24 c0 84 04 08 movl $0x80484c0,(%esp) 80483f4: e8 1f ff ff ff call 8048318 <puts@plt> 80483f9: b8 00 00 00 00 mov $0x0,%eax 80483fe: c9 leave 80483ff: c3 ret 08048400 <__libc_csu_fini>: 8048400: 55 push %ebp 8048401: 89 e5 mov %esp,%ebp 8048403: 5d pop %ebp 8048404: c3 ret 8048405: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi 8048409: 8d bc 27 00 00 00 00 lea 0x0(%edi,%eiz,1),%edi 08048410 <__libc_csu_init>: 8048410: 55 push %ebp 8048411: 89 e5 mov %esp,%ebp 8048413: 57 push %edi 8048414: 56 push %esi 8048415: 53 push %ebx 8048416: e8 4f 00 00 00 call 804846a <__i686.get_pc_thunk.bx> 804841b: 81 c3 d9 1b 00 00 add $0x1bd9,%ebx 8048421: 83 ec 1c sub $0x1c,%esp 8048424: e8 8f fe ff ff call 80482b8 <_init> 8048429: 8d bb 18 ff ff ff lea -0xe8(%ebx),%edi 804842f: 8d 83 18 ff ff ff lea -0xe8(%ebx),%eax 8048435: 29 c7 sub %eax,%edi 8048437: c1 ff 02 sar $0x2,%edi 804843a: 85 ff test %edi,%edi 804843c: 74 24 je 8048462 <__libc_csu_init+0x52> 804843e: 31 f6 xor %esi,%esi 8048440: 8b 45 10 mov 0x10(%ebp),%eax 8048443: 89 44 24 08 mov %eax,0x8(%esp) 8048447: 8b 45 0c mov 0xc(%ebp),%eax 804844a: 89 44 24 04 mov %eax,0x4(%esp) 804844e: 8b 45 08 mov 0x8(%ebp),%eax 8048451: 89 04 24 mov %eax,(%esp) 8048454: ff 94 b3 18 ff ff ff call *-0xe8(%ebx,%esi,4) 804845b: 83 c6 01 add $0x1,%esi 804845e: 39 fe cmp %edi,%esi 8048460: 72 de jb 8048440 <__libc_csu_init+0x30> 8048462: 83 c4 1c add $0x1c,%esp 8048465: 5b pop %ebx 8048466: 5e pop %esi 8048467: 5f pop %edi 8048468: 5d pop %ebp 8048469: c3 ret 0804846a <__i686.get_pc_thunk.bx>: 804846a: 8b 1c 24 mov (%esp),%ebx 804846d: c3 ret 804846e: 90 nop 804846f: 90 nop 08048470 <__do_global_ctors_aux>: 8048470: 55 push %ebp 8048471: 89 e5 mov %esp,%ebp 8048473: 53 push %ebx 8048474: 83 ec 04 sub $0x4,%esp 8048477: a1 0c 9f 04 08 mov 0x8049f0c,%eax 804847c: 83 f8 ff cmp $0xffffffff,%eax 804847f: 74 13 je 8048494 <__do_global_ctors_aux+0x24> 8048481: bb 0c 9f 04 08 mov $0x8049f0c,%ebx 8048486: 66 90 xchg %ax,%ax 8048488: 83 eb 04 sub $0x4,%ebx 804848b: ff d0 call *%eax 804848d: 8b 03 mov (%ebx),%eax 804848f: 83 f8 ff cmp $0xffffffff,%eax 8048492: 75 f4 jne 8048488 <__do_global_ctors_aux+0x18> 8048494: 83 c4 04 add $0x4,%esp 8048497: 5b pop %ebx 8048498: 5d pop %ebp 8048499: c3 ret 804849a: 90 nop 804849b: 90 nop Disassembly of section .fini: 0804849c <_fini>: 804849c: 55 push %ebp 804849d: 89 e5 mov %esp,%ebp 804849f: 53 push %ebx 80484a0: 83 ec 04 sub $0x4,%esp 80484a3: e8 00 00 00 00 call 80484a8 <_fini+0xc> 80484a8: 5b pop %ebx 80484a9: 81 c3 4c 1b 00 00 add $0x1b4c,%ebx 80484af: e8 ac fe ff ff call 8048360 <__do_global_dtors_aux> 80484b4: 59 pop %ecx 80484b5: 5b pop %ebx 80484b6: c9 leave 80484b7: c3 ret
完
readelf -all ./a.out ELF Header: Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 Class: ELF32 Data: 2's complement, little endian Version: 1 (current) OS/ABI: UNIX - System V ABI Version: 0 Type: EXEC (Executable file) Machine: Intel 80386 Version: 0x1 Entry point address: 0x8048330 Start of program headers: 52 (bytes into file) Start of section headers: 4428 (bytes into file) Flags: 0x0 Size of this header: 52 (bytes) Size of program headers: 32 (bytes) Number of program headers: 8 Size of section headers: 40 (bytes) Number of section headers: 30 Section header string table index: 27 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 08048134 000134 000013 00 A 0 0 1 [ 2] .note.ABI-tag NOTE 08048148 000148 000020 00 A 0 0 4 [ 3] .note.gnu.build-i NOTE 08048168 000168 000024 00 A 0 0 4 [ 4] .hash HASH 0804818c 00018c 000028 04 A 6 0 4 [ 5] .gnu.hash GNU_HASH 080481b4 0001b4 000020 04 A 6 0 4 [ 6] .dynsym DYNSYM 080481d4 0001d4 000050 10 A 7 1 4 [ 7] .dynstr STRTAB 08048224 000224 00004a 00 A 0 0 1 [ 8] .gnu.version VERSYM 0804826e 00026e 00000a 02 A 6 0 2 [ 9] .gnu.version_r VERNEED 08048278 000278 000020 00 A 7 1 4 [10] .rel.dyn REL 08048298 000298 000008 08 A 6 0 4 [11] .rel.plt REL 080482a0 0002a0 000018 08 A 6 13 4 [12] .init PROGBITS 080482b8 0002b8 000030 00 AX 0 0 4 [13] .plt PROGBITS 080482e8 0002e8 000040 04 AX 0 0 4 [14] .text PROGBITS 08048330 000330 00016c 00 AX 0 0 16 [15] .fini PROGBITS 0804849c 00049c 00001c 00 AX 0 0 4 [16] .rodata PROGBITS 080484b8 0004b8 000015 00 A 0 0 4 [17] .eh_frame PROGBITS 080484d0 0004d0 000004 00 A 0 0 4 [18] .ctors PROGBITS 08049f0c 000f0c 000008 00 WA 0 0 4 [19] .dtors PROGBITS 08049f14 000f14 000008 00 WA 0 0 4 [20] .jcr PROGBITS 08049f1c 000f1c 000004 00 WA 0 0 4 [21] .dynamic DYNAMIC 08049f20 000f20 0000d0 08 WA 7 0 4 [22] .got PROGBITS 08049ff0 000ff0 000004 04 WA 0 0 4 [23] .got.plt PROGBITS 08049ff4 000ff4 000018 04 WA 0 0 4 [24] .data PROGBITS 0804a00c 00100c 000008 00 WA 0 0 4 [25] .bss NOBITS 0804a014 001014 000008 00 WA 0 0 4 [26] .comment PROGBITS 00000000 001014 000048 01 MS 0 0 1 [27] .shstrtab STRTAB 00000000 00105c 0000ee 00 0 0 1 [28] .symtab SYMTAB 00000000 0015fc 000410 10 29 45 4 [29] .strtab STRTAB 00000000 001a0c 0001fa 00 0 0 1 Key to Flags: W (write), A (alloc), X (execute), M (merge), S (strings) I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown) O (extra OS processing required) o (OS specific), p (processor specific) There are no section groups in this file. Program Headers: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align PHDR 0x000034 0x08048034 0x08048034 0x00100 0x00100 R E 0x4 INTERP 0x000134 0x08048134 0x08048134 0x00013 0x00013 R 0x1 [Requesting program interpreter: /lib/ld-linux.so.2] LOAD 0x000000 0x08048000 0x08048000 0x004d4 0x004d4 R E 0x1000 LOAD 0x000f0c 0x08049f0c 0x08049f0c 0x00108 0x00110 RW 0x1000 DYNAMIC 0x000f20 0x08049f20 0x08049f20 0x000d0 0x000d0 RW 0x4 NOTE 0x000148 0x08048148 0x08048148 0x00044 0x00044 R 0x4 GNU_STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RW 0x4 GNU_RELRO 0x000f0c 0x08049f0c 0x08049f0c 0x000f4 0x000f4 R 0x1 Section to Segment mapping: Segment Sections... 00 01 .interp 02 .interp .note.ABI-tag .note.gnu.build-id .hash .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rel.dyn .rel.plt .init .plt .text .fini .rodata .eh_frame 03 .ctors .dtors .jcr .dynamic .got .got.plt .data .bss 04 .dynamic 05 .note.ABI-tag .note.gnu.build-id 06 07 .ctors .dtors .jcr .dynamic .got Dynamic section at offset 0xf20 contains 21 entries: Tag Type Name/Value 0x00000001 (NEEDED) Shared library: [libc.so.6] 0x0000000c (INIT) 0x80482b8 0x0000000d (FINI) 0x804849c 0x00000004 (HASH) 0x804818c 0x6ffffef5 (GNU_HASH) 0x80481b4 0x00000005 (STRTAB) 0x8048224 0x00000006 (SYMTAB) 0x80481d4 0x0000000a (STRSZ) 74 (bytes) 0x0000000b (SYMENT) 16 (bytes) 0x00000015 (DEBUG) 0x0 0x00000003 (PLTGOT) 0x8049ff4 0x00000002 (PLTRELSZ) 24 (bytes) 0x00000014 (PLTREL) REL 0x00000017 (JMPREL) 0x80482a0 0x00000011 (REL) 0x8048298 0x00000012 (RELSZ) 8 (bytes) 0x00000013 (RELENT) 8 (bytes) 0x6ffffffe (VERNEED) 0x8048278 0x6fffffff (VERNEEDNUM) 1 0x6ffffff0 (VERSYM) 0x804826e 0x00000000 (NULL) 0x0 Relocation section '.rel.dyn' at offset 0x298 contains 1 entries: Offset Info Type Sym.Value Sym. Name 08049ff0 00000106 R_386_GLOB_DAT 00000000 __gmon_start__ Relocation section '.rel.plt' at offset 0x2a0 contains 3 entries: Offset Info Type Sym.Value Sym. Name 0804a000 00000107 R_386_JUMP_SLOT 00000000 __gmon_start__ 0804a004 00000207 R_386_JUMP_SLOT 00000000 __libc_start_main 0804a008 00000307 R_386_JUMP_SLOT 00000000 puts There are no unwind sections in this file. Symbol table '.dynsym' contains 5 entries: Num: Value Size Type Bind Vis Ndx Name 0: 00000000 0 NOTYPE LOCAL DEFAULT UND 1: 00000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__ 2: 00000000 0 FUNC GLOBAL DEFAULT UND __libc_start_main@GLIBC_2.0 (2) 3: 00000000 0 FUNC GLOBAL DEFAULT UND puts@GLIBC_2.0 (2) 4: 080484bc 4 OBJECT GLOBAL DEFAULT 16 _IO_stdin_used Symbol table '.symtab' contains 65 entries: Num: Value Size Type Bind Vis Ndx Name 0: 00000000 0 NOTYPE LOCAL DEFAULT UND 1: 08048134 0 SECTION LOCAL DEFAULT 1 2: 08048148 0 SECTION LOCAL DEFAULT 2 3: 08048168 0 SECTION LOCAL DEFAULT 3 4: 0804818c 0 SECTION LOCAL DEFAULT 4 5: 080481b4 0 SECTION LOCAL DEFAULT 5 6: 080481d4 0 SECTION LOCAL DEFAULT 6 7: 08048224 0 SECTION LOCAL DEFAULT 7 8: 0804826e 0 SECTION LOCAL DEFAULT 8 9: 08048278 0 SECTION LOCAL DEFAULT 9 10: 08048298 0 SECTION LOCAL DEFAULT 10 11: 080482a0 0 SECTION LOCAL DEFAULT 11 12: 080482b8 0 SECTION LOCAL DEFAULT 12 13: 080482e8 0 SECTION LOCAL DEFAULT 13 14: 08048330 0 SECTION LOCAL DEFAULT 14 15: 0804849c 0 SECTION LOCAL DEFAULT 15 16: 080484b8 0 SECTION LOCAL DEFAULT 16 17: 080484d0 0 SECTION LOCAL DEFAULT 17 18: 08049f0c 0 SECTION LOCAL DEFAULT 18 19: 08049f14 0 SECTION LOCAL DEFAULT 19 20: 08049f1c 0 SECTION LOCAL DEFAULT 20 21: 08049f20 0 SECTION LOCAL DEFAULT 21 22: 08049ff0 0 SECTION LOCAL DEFAULT 22 23: 08049ff4 0 SECTION LOCAL DEFAULT 23 24: 0804a00c 0 SECTION LOCAL DEFAULT 24 25: 0804a014 0 SECTION LOCAL DEFAULT 25 26: 00000000 0 SECTION LOCAL DEFAULT 26 27: 00000000 0 FILE LOCAL DEFAULT ABS crtstuff.c 28: 08049f0c 0 OBJECT LOCAL DEFAULT 18 __CTOR_LIST__ 29: 08049f14 0 OBJECT LOCAL DEFAULT 19 __DTOR_LIST__ 30: 08049f1c 0 OBJECT LOCAL DEFAULT 20 __JCR_LIST__ 31: 08048360 0 FUNC LOCAL DEFAULT 14 __do_global_dtors_aux 32: 0804a014 1 OBJECT LOCAL DEFAULT 25 completed.7021 33: 0804a018 4 OBJECT LOCAL DEFAULT 25 dtor_idx.7023 34: 080483c0 0 FUNC LOCAL DEFAULT 14 frame_dummy 35: 00000000 0 FILE LOCAL DEFAULT ABS crtstuff.c 36: 08049f10 0 OBJECT LOCAL DEFAULT 18 __CTOR_END__ 37: 080484d0 0 OBJECT LOCAL DEFAULT 17 __FRAME_END__ 38: 08049f1c 0 OBJECT LOCAL DEFAULT 20 __JCR_END__ 39: 08048470 0 FUNC LOCAL DEFAULT 14 __do_global_ctors_aux 40: 00000000 0 FILE LOCAL DEFAULT ABS test.c 41: 08049ff4 0 OBJECT LOCAL DEFAULT 23 _GLOBAL_OFFSET_TABLE_ 42: 08049f0c 0 NOTYPE LOCAL DEFAULT 18 __init_array_end 43: 08049f0c 0 NOTYPE LOCAL DEFAULT 18 __init_array_start 44: 08049f20 0 OBJECT LOCAL DEFAULT 21 _DYNAMIC 45: 0804a00c 0 NOTYPE WEAK DEFAULT 24 data_start 46: 08048400 5 FUNC GLOBAL DEFAULT 14 __libc_csu_fini 47: 08048330 0 FUNC GLOBAL DEFAULT 14 _start 48: 00000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__ 49: 00000000 0 NOTYPE WEAK DEFAULT UND _Jv_RegisterClasses 50: 080484b8 4 OBJECT GLOBAL DEFAULT 16 _fp_hw 51: 0804849c 0 FUNC GLOBAL DEFAULT 15 _fini 52: 00000000 0 FUNC GLOBAL DEFAULT UND __libc_start_main@@GLIBC_ 53: 080484bc 4 OBJECT GLOBAL DEFAULT 16 _IO_stdin_used 54: 0804a00c 0 NOTYPE GLOBAL DEFAULT 24 __data_start 55: 0804a010 0 OBJECT GLOBAL HIDDEN 24 __dso_handle 56: 08049f18 0 OBJECT GLOBAL HIDDEN 19 __DTOR_END__ 57: 08048410 90 FUNC GLOBAL DEFAULT 14 __libc_csu_init 58: 0804a014 0 NOTYPE GLOBAL DEFAULT ABS __bss_start 59: 0804a01c 0 NOTYPE GLOBAL DEFAULT ABS _end 60: 00000000 0 FUNC GLOBAL DEFAULT UND puts@@GLIBC_2.0 61: 0804a014 0 NOTYPE GLOBAL DEFAULT ABS _edata 62: 0804846a 0 FUNC GLOBAL HIDDEN 14 __i686.get_pc_thunk.bx 63: 080483e4 28 FUNC GLOBAL DEFAULT 14 main 64: 080482b8 0 FUNC GLOBAL DEFAULT 12 _init Histogram for bucket list length (total of 3 buckets): Length Number % of total Coverage 0 0 ( 0.0%) 1 2 ( 66.7%) 50.0% 2 1 ( 33.3%) 100.0% Histogram for `.gnu.hash' bucket list length (total of 2 buckets): Length Number % of total Coverage 0 1 ( 50.0%) 1 1 ( 50.0%) 100.0% Version symbols section '.gnu.version' contains 5 entries: Addr: 000000000804826e Offset: 0x00026e Link: 6 (.dynsym) 000: 0 (*local*) 0 (*local*) 2 (GLIBC_2.0) 2 (GLIBC_2.0) 004: 1 (*global*) Version needs section '.gnu.version_r' contains 1 entries: Addr: 0x0000000008048278 Offset: 0x000278 Link: 7 (.dynstr) 000000: Version: 1 File: libc.so.6 Cnt: 1 0x0010: Name: GLIBC_2.0 Flags: none Version: 2 Notes at offset 0x00000148 with length 0x00000020: Owner Data size Description GNU 0x00000010 NT_GNU_ABI_TAG (ABI version tag) Notes at offset 0x00000168 with length 0x00000024: Owner Data size Description GNU 0x00000014 NT_GNU_BUILD_ID (unique build ID bitstring)
這個命令生成的輸出如所示。ELF Header 為該文件中所有段入口顯示了詳細的摘要。在列舉出這些 Header 中的內容之前,您可以看到 Header 的具體數目。在研究一個較大的目標文件時,該信息可能非常有用。
正如從該輸出中看到的,簡單的 a.out Hello World 文件中包含了大量有價值的細節信息,包括版本信息、柱狀圖、各種符號類型的表格,等等。通過使用本文中介紹的這幾種工具分析目標文件,您可以慢慢地對可執行程序進行研究。
除了所有這些段之外,編譯器可以將調試信息放入到目標文件中,並且還可以顯示這些信息。輸入下面的命令,仔細分析編譯器的輸出(假設您扮演了調試程序的角色):
編譯需要加-g 參數保留調試信息符號
cc -g hw.c
readelf --debug-dump a.out Contents of the .debug_aranges section: Length: 28 Version: 2 Offset into .debug_info: 0x0 Pointer Size: 4 Segment Size: 0 Address Length 080483e4 0000001c 00000000 00000000 Contents of the .debug_pubnames section: Length: 23 Version: 2 Offset into .debug_info section: 0x0 Size of area in .debug_info section: 143 Offset Name 75 main Contents of the .debug_info section: Compilation Unit @ offset 0x0: Length: 0x8b (32-bit) Version: 2 Abbrev Offset: 0 Pointer Size: 4 <0><b>: Abbrev Number: 1 (DW_TAG_compile_unit) < c> DW_AT_producer : (indirect string, offset: 0x54): GNU C 4.4.3 <10> DW_AT_language : 1 (ANSI C) <11> DW_AT_name : (indirect string, offset: 0x4d): test.c <15> DW_AT_comp_dir : (indirect string, offset: 0x42): /root <19> DW_AT_low_pc : 0x80483e4 <1d> DW_AT_high_pc : 0x8048400 <21> DW_AT_stmt_list : 0x0 <1><25>: Abbrev Number: 2 (DW_TAG_base_type) <26> DW_AT_byte_size : 4 <27> DW_AT_encoding : 7 (unsigned) <28> DW_AT_name : (indirect string, offset: 0x27): unsigned int <1><2c>: Abbrev Number: 2 (DW_TAG_base_type) <2d> DW_AT_byte_size : 1 <2e> DW_AT_encoding : 8 (unsigned char) <2f> DW_AT_name : (indirect string, offset: 0x34): unsigned char <1><33>: Abbrev Number: 2 (DW_TAG_base_type) <34> DW_AT_byte_size : 2 <35> DW_AT_encoding : 7 (unsigned) <36> DW_AT_name : (indirect string, offset: 0x0): short unsigned int <1><3a>: Abbrev Number: 2 (DW_TAG_base_type) <3b> DW_AT_byte_size : 4 <3c> DW_AT_encoding : 7 (unsigned) <3d> DW_AT_name : (indirect string, offset: 0x22): long unsigned int <1><41>: Abbrev Number: 2 (DW_TAG_base_type) <42> DW_AT_byte_size : 1 <43> DW_AT_encoding : 6 (signed char) <44> DW_AT_name : (indirect string, offset: 0x36): signed char <1><48>: Abbrev Number: 2 (DW_TAG_base_type) <49> DW_AT_byte_size : 2 <4a> DW_AT_encoding : 5 (signed) <4b> DW_AT_name : (indirect string, offset: 0x13): short int <1><4f>: Abbrev Number: 3 (DW_TAG_base_type) <50> DW_AT_byte_size : 4 <51> DW_AT_encoding : 5 (signed) <52> DW_AT_name : int <1><56>: Abbrev Number: 2 (DW_TAG_base_type) <57> DW_AT_byte_size : 8 <58> DW_AT_encoding : 5 (signed) <59> DW_AT_name : (indirect string, offset: 0x60): long long int <1><5d>: Abbrev Number: 2 (DW_TAG_base_type) <5e> DW_AT_byte_size : 8 <5f> DW_AT_encoding : 7 (unsigned) <60> DW_AT_name : (indirect string, offset: 0x1d): long long unsigned int <1><64>: Abbrev Number: 2 (DW_TAG_base_type) <65> DW_AT_byte_size : 4 <66> DW_AT_encoding : 5 (signed) <67> DW_AT_name : (indirect string, offset: 0x65): long int <1><6b>: Abbrev Number: 4 (DW_TAG_base_type) <6c> DW_AT_byte_size : 4 <6d> DW_AT_encoding : 7 (unsigned) <1><6e>: Abbrev Number: 2 (DW_TAG_base_type) <6f> DW_AT_byte_size : 1 <70> DW_AT_encoding : 6 (signed char) <71> DW_AT_name : (indirect string, offset: 0x3d): char <1><75>: Abbrev Number: 5 (DW_TAG_subprogram) <76> DW_AT_external : 1 <77> DW_AT_name : (indirect string, offset: 0x48): main <7b> DW_AT_decl_file : 1 <7c> DW_AT_decl_line : 4 <7d> DW_AT_prototyped : 1 <7e> DW_AT_type : <0x4f> <82> DW_AT_low_pc : 0x80483e4 <86> DW_AT_high_pc : 0x8048400 <8a> DW_AT_frame_base : 0x0 (location list) Contents of the .debug_abbrev section: Number TAG 1 DW_TAG_compile_unit [has children] DW_AT_producer DW_FORM_strp DW_AT_language DW_FORM_data1 DW_AT_name DW_FORM_strp DW_AT_comp_dir DW_FORM_strp DW_AT_low_pc DW_FORM_addr DW_AT_high_pc DW_FORM_addr DW_AT_stmt_list DW_FORM_data4 2 DW_TAG_base_type [no children] DW_AT_byte_size DW_FORM_data1 DW_AT_encoding DW_FORM_data1 DW_AT_name DW_FORM_strp 3 DW_TAG_base_type [no children] DW_AT_byte_size DW_FORM_data1 DW_AT_encoding DW_FORM_data1 DW_AT_name DW_FORM_string 4 DW_TAG_base_type [no children] DW_AT_byte_size DW_FORM_data1 DW_AT_encoding DW_FORM_data1 5 DW_TAG_subprogram [no children] DW_AT_external DW_FORM_flag DW_AT_name DW_FORM_strp DW_AT_decl_file DW_FORM_data1 DW_AT_decl_line DW_FORM_data1 DW_AT_prototyped DW_FORM_flag DW_AT_type DW_FORM_ref4 DW_AT_low_pc DW_FORM_addr DW_AT_high_pc DW_FORM_addr DW_AT_frame_base DW_FORM_data4 Raw dump of debug contents of section .debug_line: Offset: 0x0 Length: 51 DWARF Version: 2 Prologue Length: 29 Minimum Instruction Length: 1 Initial value of 'is_stmt': 1 Line Base: -5 Line Range: 14 Opcode Base: 13 Opcodes: Opcode 1 has 0 args Opcode 2 has 1 args Opcode 3 has 1 args Opcode 4 has 1 args Opcode 5 has 1 args Opcode 6 has 0 args Opcode 7 has 0 args Opcode 8 has 0 args Opcode 9 has 1 args Opcode 10 has 0 args Opcode 11 has 0 args Opcode 12 has 1 args The Directory Table is empty. The File Name Table: Entry Dir Time Size Name 1 0 0 0 test.c Line Number Statements: Extended opcode 2: set Address to 0x80483e4 Special opcode 9: advance Address by 0 to 0x80483e4 and Line by 4 to 5 Special opcode 132: advance Address by 9 to 0x80483ed and Line by 1 to 6 Special opcode 174: advance Address by 12 to 0x80483f9 and Line by 1 to 7 Special opcode 76: advance Address by 5 to 0x80483fe and Line by 1 to 8 Advance PC by 2 to 0x8048400 Extended opcode 1: End of Sequence Contents of the .debug_frame section: 00000000 00000010 ffffffff CIE Version: 1 Augmentation: "" Code alignment factor: 1 Data alignment factor: -4 Return address column: 8 DW_CFA_def_cfa: r4 (esp) ofs 4 DW_CFA_offset: r8 (eip) at cfa-4 DW_CFA_nop DW_CFA_nop 00000014 00000014 00000000 FDE cie=00000000 pc=080483e4..08048400 DW_CFA_advance_loc: 1 to 080483e5 DW_CFA_def_cfa_offset: 8 DW_CFA_advance_loc: 2 to 080483e7 DW_CFA_offset: r5 (ebp) at cfa-8 DW_CFA_def_cfa_register: r5 (ebp) Contents of the .debug_str section: 0x00000000 73686f72 7420756e 7369676e 65642069 short unsigned i 0x00000010 6e740073 686f7274 20696e74 006c6f6e nt.short int.lon 0x00000020 67206c6f 6e672075 6e736967 6e656420 g long unsigned 0x00000030 696e7400 756e7369 676e6564 20636861 int.unsigned cha 0x00000040 72002f72 6f6f7400 6d61696e 00746573 r./root.main.tes 0x00000050 742e6300 474e5520 4320342e 342e3300 t.c.GNU C 4.4.3. 0x00000060 6c6f6e67 206c6f6e 6720696e 7400 long long int. Contents of the .debug_loc section: Offset Begin End Expression 00000000 080483e4 080483e5 (DW_OP_breg4 (esp): 4) 00000000 080483e5 080483e7 (DW_OP_breg4 (esp): 8) 00000000 080483e7 08048400 (DW_OP_breg5 (ebp): 8) 00000000 <End of list>
這個命令生成的輸出如 所示。調試工具,如 GDB,可以讀取這些調試信息,並且當程序在調試器中運行的同時,您可以使用該工具顯示更具描述性的標記,而不是對代碼進行反匯編時的原始地址值。
參考