objdump

顯示二進制文件信息

補充說明

objdump命令 是用查看目標文件或者可執行的目標文件的構成的gcc工具。

選項

  1-a --archive-headers 
  2# 顯示檔案庫的成員信息,類似ls -l將lib*.a的信息列出。 
  3
  4-b bfdname --target=bfdname 
  5# 指定目標碼格式。這不是必須的,objdump能自動識別許多格式,比如: 
  6
  7objdump -b oasys -m vax -h fu.o 
  8# 顯示fu.o的頭部摘要信息,明確指出該文件是Vax系統下用Oasys編譯器生成的目標文件。objdump -i將給出這裏可以指定的目標碼格式列表。 
  9
 10-C --demangle 
 11# 將底層的符號名解碼成用戶級名字,除了去掉所開頭的下劃線之外,還使得C++函數名以可理解的方式顯示出來。 
 12--debugging 
 13-g 
 14# 顯示調試信息。企圖解析保存在文件中的調試信息並以C語言的語法顯示出來。僅僅支持某些類型的調試信息。有些其他的格式被readelf -w支持。 
 15
 16-e --debugging-tags 
 17# 類似-g選項,但是生成的信息是和ctags工具相兼容的格式。 
 18--disassemble 
 19-d 
 20# 從objfile中反彙編那些特定指令機器碼的section。 
 21
 22-D --disassemble-all 
 23# 與 -d 類似,但反彙編所有section. 
 24
 25--prefix-addresses 
 26# 反彙編的時候,顯示每一行的完整地址。這是一種比較老的反彙編格式。 
 27
 28-EB 
 29-EL 
 30--endian={big|little} 
 31# 指定目標文件的小端。這個項將影響反彙編出來的指令。在反彙編的文件沒描述小端信息的時候用。例如S-records. 
 32
 33-f 
 34--file-headers 
 35顯示objfile中每個文件的整體頭部摘要信息。 
 36
 37-h 
 38--section-headers 
 39--headers 
 40顯示目標文件各個section的頭部摘要信息。 
 41
 42-H 
 43--help 
 44簡短的幫助信息。 
 45
 46-i 
 47--info 
 48顯示對於 -b 或者 -m 選項可用的架構和目標格式列表。 
 49
 50-j name
 51--section=name 
 52僅僅顯示指定名稱爲name的section的信息 
 53
 54-l
 55--line-numbers 
 56用文件名和行號標註相應的目標代碼,僅僅和-d、-D或者-r一起使用使用-ld和使用-d的區別不是很大,在源碼級調試的時候有用,要求編譯時使用了-g之類的調試編譯選項。 
 57
 58-m machine 
 59--architecture=machine 
 60指定反彙編目標文件時使用的架構,當待反彙編文件本身沒描述架構信息的時候(比如S-records),這個選項很有用。可以用-i選項列出這裏能夠指定的架構. 
 61
 62--reloc 
 63-r 
 64顯示文件的重定位入口。如果和-d或者-D一起使用,重定位部分以反彙編後的格式顯示出來。 
 65
 66--dynamic-reloc 
 67-R 
 68顯示文件的動態重定位入口,僅僅對於動態目標文件意義,比如某些共享庫。 
 69
 70-s 
 71--full-contents 
 72顯示指定section的完整內容。默認所有的非空section都會被顯示。 
 73
 74-S 
 75--source 
 76儘可能反彙編出源代碼,尤其當編譯的時候指定了-g這種調試參數時,效果比較明顯。隱含了-d參數。 
 77
 78--show-raw-insn 
 79反彙編的時候,顯示每條彙編指令對應的機器碼,如不指定--prefix-addresses,這將是缺省選項。 
 80
 81--no-show-raw-insn 
 82反彙編時,不顯示彙編指令的機器碼,如不指定--prefix-addresses,這將是缺省選項。 
 83
 84--start-address=address 
 85從指定地址開始顯示數據,該選項影響-d、-r和-s選項的輸出。 
 86
 87--stop-address=address 
 88顯示數據直到指定地址爲止,該項影響-d、-r和-s選項的輸出。 
 89
 90-t 
 91--syms 
 92顯示文件的符號表入口。類似於nm -s提供的信息 
 93
 94-T 
 95--dynamic-syms 
 96顯示文件的動態符號表入口,僅僅對動態目標文件意義,比如某些共享庫。它顯示的信息類似於 nm -D|--dynamic 顯示的信息。 
 97
 98-V 
 99--version 
100版本信息 
101
102--all-headers 
103-x 
104顯示所可用的頭信息,包括符號表、重定位入口。-x 等價於-a -f -h -r -t 同時指定。 
105
106-z 
107--disassemble-zeroes 
108一般反彙編輸出將省略大塊的零,該選項使得這些零塊也被反彙編。 
109
110@file 可以將選項集中到一個文件中,然後使用這個@file選項載入。

實例

首先,在給出後面大部分測試所基於的源代碼以及編譯指令。 源代碼如下: 

1root@localhost [test]# nl mytest.cpp 
1void printTest() {
2    char a;
3    a = 'a';
4}
5
6void printTest2() {
7int a = 2;
8a+=2;
9} 

對以上源代碼進行編譯,如下: 

1[root@localhost test]# g++ -c -g mytest.cpp 

這裏,生成的文件是mytest.o,爲了方便測試包含了調試的信息,對可執行文件的測試,顯示的結果類似。 

**查看當前使用的objdump的版本號: **

1[root@localhost test]# objdump -V 
2GNU objdump 2.17.50.0.6-14.el5 20061020 
3Copyright 2005 free Software Foundation, Inc. 
4This program is free software; you may redistribute it under the terms of 
5the GNU General Public License.  This program has absolutely no warranty. 

**查看檔案庫文件中的信息: **

1[root@localhost test]# objdump -a libmy2.a 
2In archive libmy2.a: 
3myfile.o:     file format elf32-i386 
4rwxrwxrwx 0/0   2724 Nov 16 16:06 2009 myfile.o 
5mytest.o:     file format elf32-i386 
6rw-r--r-- 0/0    727 Jul 13 15:32 2011 mytest.o 

*這裏,libmy2.a是一個使用ar命令將多個.o目標文件打包而生成的靜態庫。命令的輸出類似ar -tv,相比較ar -tv輸出如下: **

1[root@localhost test]# ar -tv libmy2.a 
2rwxrwxrwx 0/0   2724 Nov 16 16:06 2009 myfile.o 
3rw-r--r-- 0/0    727 Jul 13 15:32 2011 mytest.o 

顯示可用的架構和目標結構列表: 

 1[root@localhost test]# objdump -i 
 2BFD header file version 2.17.50.0.6-14.el5 20061020 
 3elf32-i386 
 4(header little endian, data little endian) 
 5  i386 
 6a.out-i386-linux 
 7(header little endian, data little endian) 
 8  i386 
 9efi-app-ia32 
10(header little endian, data little endian) 
11  i386 
12elf64-x86-64 
13(header little endian, data little endian) 
14  i386 
15elf64-little 
16(header little endian, data little endian) 
17  i386 
18elf64-big 
19(header big endian, data big endian) 
20  i386 
21elf32-little 
22(header little endian, data little endian) 
23  i386 
24elf32-big 
25(header big endian, data big endian) 
26  i386 
27srec 
28(header endianness unknown, data endianness unknown) 
29  i386 
30symbolsrec 
31(header endianness unknown, data endianness unknown) 
32  i386 
33tekhex 
34(header endianness unknown, data endianness unknown) 
35  i386 
36binary 
37(header endianness unknown, data endianness unknown) 
38  i386 
39ihex 
40(header endianness unknown, data endianness unknown) 
41  i386 
42trad-core 
43(header endianness unknown, data endianness unknown) 
44
45              elf32-i386 a.out-i386-linux efi-app-ia32 elf64-x86-64 
46          i386 elf32-i386 a.out-i386-linux efi-app-ia32 elf64-x86-64 
47
48              elf64-little elf64-big elf32-little elf32-big srec symbolsrec 
49          i386 elf64-little elf64-big elf32-little elf32-big srec symbolsrec 
50
51              tekhex binary ihex trad-core 
52          i386 tekhex binary ihex --------- 

這裏,顯示的信息是相對於 -b 或者 -m 選項可用的架構和目標格式列表。 

**顯示mytest.o文件中的text段的內容: **

1[root@localhost test]# objdump --section=.text -s mytest.o 
2mytest.o:     file format elf32-i386 
3Contents of section .text: 
40000 5589e583 ec10c645 ff61c9c3 5589e583  U......E.a..U... 
50010 ec10c745 fc020000 008345fc 02c9c3    ...E......E.... 

這裏注意,不能單獨使用-j或者--section,例如objdump --section=.text mytest.o是不會運行成功的。 

**反彙編mytest.o中的text段內容,並儘可能用源代碼形式表示: **

 1[root@localhost test]# objdump -j .text -S mytest.o 
 2mytest.o:     file format elf32-i386 
 3Disassembly of section .text: 
 400000000 <_Z9printTestv>: 
 5void printTest() 
 6   0:   55                      push   %ebp 
 7   1:   89 e5                   mov    %esp,%ebp 
 8   3:   83 ec 10                sub    $0x10,%esp 
 9{ 
10        char a; 
11        a = 'a'; 
12   6:   c6 45 ff 61             movb   $0x61,0xffffffff(%ebp) 
13} 
14   a:   c9                      leave  
15   b:   c3                      ret    
16
17000000c <_Z10printTest2v>: 
18void printTest2() 
19   c:   55                      push   %ebp 
20   d:   89 e5                   mov    %esp,%ebp 
21   f:   83 ec 10                sub    $0x10,%esp 
22{ 
23        int a = 2; 
24  12:   c7 45 fc 02 00 00 00    movl   $0x2,0xfffffffc(%ebp) 
25        a+=2; 
26  19:   83 45 fc 02             addl   $0x2,0xfffffffc(%ebp) 
27} 
28  1d:   c9                      leave  
29  1e:   c3                      ret    

這裏注意,不能單獨使用-j或者--section,例如objdump -j .text mytest.o是不會運行成功的。另外-S命令對於包含調試信息的目標文件,顯示的效果比較好,如果編譯時沒有指定g++的-g選項,那麼目標文件就不包含調試信息,那麼顯示效果就差多了。 

**反彙編出mytest.o的源代碼: **

 1[root@localhost test]# objdump -S mytest.o 
 2mytest.o:     file format elf32-i386 
 3
 4Disassembly of section .text: 
 5
 600000000 <_Z9printTestv>: 
 7void printTest() 
 8   0:   55                      push   %ebp 
 9   1:   89 e5                   mov    %esp,%ebp 
10   3:   83 ec 10                sub    $0x10,%esp 
11{ 
12        char a; 
13        a = 'a'; 
14   6:   c6 45 ff 61             movb   $0x61,0xffffffff(%ebp) 
15} 
16   a:   c9                      leave  
17   b:   c3                      ret    
18
190000000c <_Z10printTest2v>: 
20void printTest2() 
21   c:   55                      push   %ebp 
22   d:   89 e5                   mov    %esp,%ebp 
23   f:   83 ec 10                sub    $0x10,%esp 
24{ 
25       int a = 2; 
26  12:   c7 45 fc 02 00 00 00    movl   $0x2,0xfffffffc(%ebp) 
27        a+=2; 
28  19:   83 45 fc 02             addl   $0x2,0xfffffffc(%ebp) 
29} 
30  1d:   c9                      leave  
31  1e:   c3                      ret    

這裏,尤其當編譯的時候指定了-g這種調試參數時,反彙編的效果比較明顯。隱含了-d參數。 

**顯示文件的符號表入口: **

 1[root@localhost test]# objdump -t mytest.o 
 2mytest.o:     file format elf32-i386 
 3
 4SYMBOL TABLE: 
 500000000 l    df *ABS*  00000000 mytest.cpp 
 600000000 l    d  .text  00000000 .text 
 700000000 l    d  .data  00000000 .data 
 800000000 l    d  .bss   00000000 .bss 
 900000000 l    d  .debug_abbrev  00000000 .debug_abbrev 
1000000000 l    d  .debug_info    00000000 .debug_info 
1100000000 l    d  .debug_line    00000000 .debug_line 
1200000000 l    d  .debug_frame   00000000 .debug_frame 
1300000000 l    d  .debug_loc     00000000 .debug_loc 
1400000000 l    d  .debug_pubnames        00000000 .debug_pubnames 
1500000000 l    d  .debug_aranges 00000000 .debug_aranges 
1600000000 l    d  .note.GNU-stack        00000000 .note.GNU-stack 
1700000000 l    d  .comment       00000000 .comment 
1800000000 g     F .text  0000000c _Z9printTestv 
1900000000         *UND*  00000000 __gxx_personality_v0 
200000000c g     F .text  00000013 _Z10printTest2v 

這裏,輸出的信息類似nm -s命令的輸出,相比較之下,nm命令的輸出如下: 

1[root@localhost test]# nm -s mytest.o 
20000000c T _Z10printTest2v 
300000000 T _Z9printTestv 
4         U __gxx_personality_v0 

**顯示文件的符號表入口,將底層符號解碼並表示成用戶級別: **

 1[root@localhost test]# objdump -t -C mytest.o 
 2mytest.o:     file format elf32-i386 
 3SYMBOL TABLE: 
 400000000 l    df *ABS*  00000000 mytest.cpp 
 500000000 l    d  .text  00000000 .text 
 600000000 l    d  .data  00000000 .data 
 700000000 l    d  .bss   00000000 .bss 
 800000000 l    d  .debug_abbrev  00000000 .debug_abbrev 
 900000000 l    d  .debug_info    00000000 .debug_info 
1000000000 l    d  .debug_line    00000000 .debug_line 
1100000000 l    d  .debug_frame   00000000 .debug_frame 
1200000000 l    d  .debug_loc     00000000 .debug_loc 
1300000000 l    d  .debug_pubnames        00000000 .debug_pubnames 
1400000000 l    d  .debug_aranges 00000000 .debug_aranges 
1500000000 l    d  .note.GNU-stack        00000000 .note.GNU-stack 
1600000000 l    d  .comment       00000000 .comment 
1700000000 g     F .text  0000000c printTest() 
1800000000         *UND*  00000000 __gxx_personality_v0 
190000000c g     F .text  00000013 printTest2() 

這裏,和沒-C相比,printTest2函數可讀性增加了。 

**反彙編目標文件的特定機器碼段: **

 1[root@localhost test]# objdump -d mytest.o 
 2mytest.o:     file format elf32-i386 
 3Disassembly of section .text: 
 4
 500000000 <_Z9printTestv>: 
 6   0:   55                      push   %ebp 
 7   1:   89 e5                   mov    %esp,%ebp 
 8   3:   83 ec 10                sub    $0x10,%esp 
 9   6:   c6 45 ff 61             movb   $0x61,0xffffffff(%ebp) 
10   a:   c9                      leave  
11  b:   c3                      ret    
12
130000000c <_Z10printTest2v>: 
14   c:   55                      push   %ebp 
15   d:   89 e5                   mov    %esp,%ebp 
16   f:   83 ec 10                sub    $0x10,%esp 
17  12:   c7 45 fc 02 00 00 00    movl   $0x2,0xfffffffc(%ebp) 
18  19:   83 45 fc 02             addl   $0x2,0xfffffffc(%ebp) 
19  1d:   c9                      leave  
20  1e:   c3                      ret    

這裏,對text段的內容進行了反彙編。 

**反彙編特定段,並將彙編代碼對應的文件名稱和行號對應上: **

 1[root@localhost test]# objdump -d -l mytest.o
 2mytest.o:     file format elf32-i386 
 3Disassembly of section .text: 
 4
 500000000 <_Z9printTestv>: 
 6_Z9printTestv(): 
 7/root/test/04_libraryTest/mytest.cpp:1 
 8   0:   55                      push   %ebp 
 9   1:   89 e5                   mov    %esp,%ebp 
10   3:   83 ec 10                sub    $0x10,%esp 
11/root/test/04_libraryTest/mytest.cpp:4 
12   6:   c6 45 ff 61             movb   $0x61,0xffffffff(%ebp) 
13/root/test/04_libraryTest/mytest.cpp:5 
14   a:   c9                      leave  
15   b:   c3                      ret    
16
170000000c <_Z10printTest2v>: 
18_Z10printTest2v(): 
19/root/test/04_libraryTest/mytest.cpp:6 
20   c:   55                      push   %ebp 
21   d:   89 e5                   mov    %esp,%ebp 
22   f:   83 ec 10                sub    $0x10,%esp 
23/root/test/04_libraryTest/mytest.cpp:8 
24  12:   c7 45 fc 02 00 00 00    movl   $0x2,0xfffffffc(%ebp) 
25/root/test/04_libraryTest/mytest.cpp:9 
26  19:   83 45 fc 02             addl   $0x2,0xfffffffc(%ebp) 
27/root/test/04_libraryTest/mytest.cpp:10 
28  1d:   c9                      leave  
29  1e:   c3                      ret    

這裏,項"-d"從objfile中反彙編那些特定指令機器碼的section,而使用"-l"指定用文件名和行號標註相應的目標代碼,僅僅和-d、-D或者-r一起使用,使用-ld和使用-d的區別不是很大,在源碼級調試的時候有用,要求編譯時使用了-g之類的調試編譯選項。 

**顯示目標文件各個段的頭部摘要信息: **

 1[root@localhost test]# objdump -h mytest.o 
 2mytest.o:     file format elf32-i386 
 3
 4Sections: 
 5Idx Name          Size      VMA       LMA       File off  Algn 
 6  0 .text         0000001f  00000000  00000000  00000034  2**2 
 7                  CONTENTS, ALLOC, LOAD, readonly, CODE 
 8  1 .data         00000000  00000000  00000000  00000054  2**2 
 9                  CONTENTS, ALLOC, LOAD, DATA 
10  2 .bss          00000000  00000000  00000000  00000054  2**2 
11                  ALLOC 
12  3 .debug_abbrev 00000046  00000000  00000000  00000054  2**0 
13                  CONTENTS, READONLY, DEBUGGING 
14  4 .debug_info   000000ed  00000000  00000000  0000009a  2**0 
15                  CONTENTS, RELOC, READONLY, DEBUGGING 
16  5 .debug_line   0000003e  00000000  00000000  00000187  2**0 
17                  CONTENTS, RELOC, READONLY, DEBUGGING 
18  6 .debug_frame  00000044  00000000  00000000  000001c8  2**2 
19                  CONTENTS, RELOC, READONLY, DEBUGGING 
20  7 .debug_loc    00000058  00000000  00000000  0000020c  2**0 
21                  CONTENTS, READONLY, DEBUGGING 
22  8 .debug_pubnames 0000002f  00000000  00000000  00000264  2**0 
23                  CONTENTS, RELOC, READONLY, DEBUGGING 
24  9 .debug_aranges 00000020  00000000  00000000  00000293  2**0 
25                  CONTENTS, RELOC, READONLY, DEBUGGING 
2610 .comment      0000002e  00000000  00000000  000002b3  2**0 
27                  CONTENTS, READONLY 
2811 .note.GNU-stack 00000000  00000000  00000000  000002e1  2**0 
29                  CONTENTS, READONLY 

這裏,更多的內容參見man objdump中的這個選項。

來源:https://github.com/jaywcjlove/linux-command

最後修改於: Wednesday, January 31, 2024

相關文章:

翻譯: