轉載:objdump指令_Linux objdump 指令用法詳解:顯示二進制檔案資訊 (linuxde.net)
objdump指令
程式設計開發
objdump指令是用檢視目标檔案或者可執行的目标檔案的構成的gcc工具。
選項
--archive-headers
-a
顯示檔案庫的成員資訊,類似ls -l将lib*.a的資訊列出。
-b bfdname
--target=bfdname
指定目标碼格式。這不是必須的,objdump能自動識别許多格式,比如:
objdump -b oasys -m vax -h fu.o
顯示fu.o的頭部摘要資訊,明确指出該檔案是Vax系統下用Oasys編譯器生成的目标檔案。objdump -i将給出這裡可以指定的目标碼格式清單。
-C
--demangle
将底層的符号名解碼成使用者級名字,除了去掉所開頭的下劃線之外,還使得C++函數名以可了解的方式顯示出來。
--debugging
-g
顯示調試資訊。企圖解析儲存在檔案中的調試資訊并以C語言的文法顯示出來。僅僅支援某些類型的調試資訊。有些其他的格式被readelf -w支援。
-e
--debugging-tags
類似-g選項,但是生成的資訊是和ctags工具相相容的格式。
--disassemble
-d
從objfile中反彙編那些特定指令機器碼的section。
-D
--disassemble-all
與 -d 類似,但反彙編所有section.
--prefix-addresses
反彙編的時候,顯示每一行的完整位址。這是一種比較老的反彙編格式。
-EB
-EL
--endian={big|little}
指定目标檔案的小端。這個項将影響反彙編出來的指令。在反彙編的檔案沒描述小端資訊的時候用。例如S-records.
-f
--file-headers
顯示objfile中每個檔案的整體頭部摘要資訊。
-h
--section-headers
--headers
顯示目标檔案各個section的頭部摘要資訊。
-H
--help
簡短的幫助資訊。
-i
--info
顯示對于 -b 或者 -m 選項可用的架構和目标格式清單。
-j name
--section=name
僅僅顯示指定名稱為name的section的資訊
-l
--line-numbers
用檔案名和行号标注相應的目标代碼,僅僅和-d、-D或者-r一起使用使用-ld和使用-d的差別不是很大,在源碼級調試的時候有用,要求編譯時使用了-g之類的調試編譯選項。
-m machine
--architecture=machine
指定反彙編目标檔案時使用的架構,當待反彙編檔案本身沒描述架構資訊的時候(比如S-records),這個選項很有用。可以用-i選項列出這裡能夠指定的架構.
--reloc
-r
顯示檔案的重定位入口。如果和-d或者-D一起使用,重定位部分以反彙編後的格式顯示出來。
--dynamic-reloc
-R
顯示檔案的動态重定位入口,僅僅對于動态目标檔案意義,比如某些共享庫。
-s
--full-contents
顯示指定section的完整内容。預設所有的非空section都會被顯示。
-S
--source
盡可能反彙編出源代碼,尤其當編譯的時候指定了-g這種調試參數時,效果比較明顯。隐含了-d參數。
--show-raw-insn
反彙編的時候,顯示每條彙編指令對應的機器碼,如不指定--prefix-addresses,這将是預設選項。
--no-show-raw-insn
反彙編時,不顯示彙編指令的機器碼,如不指定--prefix-addresses,這将是預設選項。
--start-address=address
從指定位址開始顯示資料,該選項影響-d、-r和-s選項的輸出。
--stop-address=address
顯示資料直到指定位址為止,該項影響-d、-r和-s選項的輸出。
-t
--syms
顯示檔案的符号表入口。類似于nm -s提供的資訊
-T
--dynamic-syms
顯示檔案的動态符号表入口,僅僅對動态目标檔案意義,比如某些共享庫。它顯示的資訊類似于 nm -D|--dynamic 顯示的資訊。
-V
--version
版本資訊
--all-headers
-x
顯示所可用的頭資訊,包括符号表、重定位入口。-x 等價于-a -f -h -r -t 同時指定。
-z
--disassemble-zeroes
一般反彙編輸出将省略大塊的零,該選項使得這些零塊也被反彙編。
@file 可以将選項集中到一個檔案中,然後使用這個@file選項載入。
執行個體
首先,在給出後面大部分測試所基于的源代碼以及編譯指令。 源代碼如下:
[root@localhost test]# nl mytest.cpp
void printTest() {
char a;
a = 'a';
}
void printTest2() {
int a = 2;
a+=2;
}
對以上源代碼進行編譯,如下:
[root@localhost test]# g++ -c -g mytest.cpp
這裡,生成的檔案是mytest.o,為了友善測試包含了調試的資訊,對可執行檔案的測試,顯示的結果類似。
檢視目前使用的objdump的版本号:
[root@localhost test]# objdump -V
GNU objdump 2.17.50.0.6-14.el5 20061020
Copyright 2005 free Software Foundation, Inc.
This program is free software; you may redistribute it under the terms of
the GNU General Public License. This program has absolutely no warranty.
檢視檔案庫檔案中的資訊:
[root@localhost test]# objdump -a libmy2.a
In archive libmy2.a:
myfile.o: file format elf32-i386
rwxrwxrwx 0/0 2724 Nov 16 16:06 2009 myfile.o
mytest.o: file format elf32-i386
rw-r--r-- 0/0 727 Jul 13 15:32 2011 mytest.o
這裡,libmy2.a是一個使用ar指令将多個*.o目标檔案打包而生成的靜态庫。指令的輸出類似
ar -tv
,相比較
ar -tv
輸出如下:
[root@localhost test]# ar -tv libmy2.a
rwxrwxrwx 0/0 2724 Nov 16 16:06 2009 myfile.o
rw-r--r-- 0/0 727 Jul 13 15:32 2011 mytest.o
顯示可用的架構和目标結構清單:
[root@localhost test]# objdump -i
BFD header file version 2.17.50.0.6-14.el5 20061020
elf32-i386
(header little endian, data little endian)
i386
a.out-i386-linux
(header little endian, data little endian)
i386
efi-app-ia32
(header little endian, data little endian)
i386
elf64-x86-64
(header little endian, data little endian)
i386
elf64-little
(header little endian, data little endian)
i386
elf64-big
(header big endian, data big endian)
i386
elf32-little
(header little endian, data little endian)
i386
elf32-big
(header big endian, data big endian)
i386
srec
(header endianness unknown, data endianness unknown)
i386
symbolsrec
(header endianness unknown, data endianness unknown)
i386
tekhex
(header endianness unknown, data endianness unknown)
i386
binary
(header endianness unknown, data endianness unknown)
i386
ihex
(header endianness unknown, data endianness unknown)
i386
trad-core
(header endianness unknown, data endianness unknown)
elf32-i386 a.out-i386-linux efi-app-ia32 elf64-x86-64
i386 elf32-i386 a.out-i386-linux efi-app-ia32 elf64-x86-64
elf64-little elf64-big elf32-little elf32-big srec symbolsrec
i386 elf64-little elf64-big elf32-little elf32-big srec symbolsrec
tekhex binary ihex trad-core
i386 tekhex binary ihex ---------
這裡,顯示的資訊是相對于 -b 或者 -m 選項可用的架構和目标格式清單。
顯示mytest.o檔案中的text段的内容:
[root@localhost test]# objdump --section=.text -s mytest.o
mytest.o: file format elf32-i386
Contents of section .text:
0000 5589e583 ec10c645 ff61c9c3 5589e583 U......E.a..U...
0010 ec10c745 fc020000 008345fc 02c9c3 ...E......E....
這裡注意,不能單獨使用-j或者--section,例如
objdump --section=.text mytest.o
是不會運作成功的。
反彙編mytest.o中的text段内容,并盡可能用源代碼形式表示:
[root@localhost test]# objdump -j .text -S mytest.o
mytest.o: file format elf32-i386
Disassembly of section .text:
00000000 <_Z9printTestv>:
void printTest()
0: 55 push %ebp
1: 89 e5 mov %esp,%ebp
3: 83 ec 10 sub $0x10,%esp
{
char a;
a = 'a';
6: c6 45 ff 61 movb $0x61,0xffffffff(%ebp)
}
a: c9 leave
b: c3 ret
000000c <_Z10printTest2v>:
void printTest2()
c: 55 push %ebp
d: 89 e5 mov %esp,%ebp
f: 83 ec 10 sub $0x10,%esp
{
int a = 2;
12: c7 45 fc 02 00 00 00 movl $0x2,0xfffffffc(%ebp)
a+=2;
19: 83 45 fc 02 addl $0x2,0xfffffffc(%ebp)
}
1d: c9 leave
1e: c3 ret
objdump -j .text mytest.o是不會運作成功的
。另外-S指令對于包含調試資訊的目标檔案,顯示的效果比較好,如果編譯時沒有指定g++的-g選項,那麼目标檔案就不包含調試資訊,那麼顯示效果就差多了。
反彙編出mytest.o的源代碼:
[root@localhost test]# objdump -S mytest.o
mytest.o: file format elf32-i386
Disassembly of section .text:
00000000 <_Z9printTestv>:
void printTest()
0: 55 push %ebp
1: 89 e5 mov %esp,%ebp
3: 83 ec 10 sub $0x10,%esp
{
char a;
a = 'a';
6: c6 45 ff 61 movb $0x61,0xffffffff(%ebp)
}
a: c9 leave
b: c3 ret
0000000c <_Z10printTest2v>:
void printTest2()
c: 55 push %ebp
d: 89 e5 mov %esp,%ebp
f: 83 ec 10 sub $0x10,%esp
{
int a = 2;
12: c7 45 fc 02 00 00 00 movl $0x2,0xfffffffc(%ebp)
a+=2;
19: 83 45 fc 02 addl $0x2,0xfffffffc(%ebp)
}
1d: c9 leave
1e: c3 ret
這裡,尤其當編譯的時候指定了-g這種調試參數時,反彙編的效果比較明顯。隐含了-d參數。
顯示檔案的符号表入口:
[root@localhost test]# objdump -t mytest.o
mytest.o: file format elf32-i386
SYMBOL TABLE:
00000000 l df *ABS* 00000000 mytest.cpp
00000000 l d .text 00000000 .text
00000000 l d .data 00000000 .data
00000000 l d .bss 00000000 .bss
00000000 l d .debug_abbrev 00000000 .debug_abbrev
00000000 l d .debug_info 00000000 .debug_info
00000000 l d .debug_line 00000000 .debug_line
00000000 l d .debug_frame 00000000 .debug_frame
00000000 l d .debug_loc 00000000 .debug_loc
00000000 l d .debug_pubnames 00000000 .debug_pubnames
00000000 l d .debug_aranges 00000000 .debug_aranges
00000000 l d .note.GNU-stack 00000000 .note.GNU-stack
00000000 l d .comment 00000000 .comment
00000000 g F .text 0000000c _Z9printTestv
00000000 *UND* 00000000 __gxx_personality_v0
0000000c g F .text 00000013 _Z10printTest2v
這裡,輸出的資訊類似
nm -s
指令的輸出,相比較之下,nm指令的輸出如下:
[root@localhost test]# nm -s mytest.o
0000000c T _Z10printTest2v
00000000 T _Z9printTestv
U __gxx_personality_v0
顯示檔案的符号表入口,将底層符号解碼并表示成使用者級别:
[root@localhost test]# objdump -t -C mytest.o
mytest.o: file format elf32-i386
SYMBOL TABLE:
00000000 l df *ABS* 00000000 mytest.cpp
00000000 l d .text 00000000 .text
00000000 l d .data 00000000 .data
00000000 l d .bss 00000000 .bss
00000000 l d .debug_abbrev 00000000 .debug_abbrev
00000000 l d .debug_info 00000000 .debug_info
00000000 l d .debug_line 00000000 .debug_line
00000000 l d .debug_frame 00000000 .debug_frame
00000000 l d .debug_loc 00000000 .debug_loc
00000000 l d .debug_pubnames 00000000 .debug_pubnames
00000000 l d .debug_aranges 00000000 .debug_aranges
00000000 l d .note.GNU-stack 00000000 .note.GNU-stack
00000000 l d .comment 00000000 .comment
00000000 g F .text 0000000c printTest()
00000000 *UND* 00000000 __gxx_personality_v0
0000000c g F .text 00000013 printTest2()
這裡,和沒-C相比,printTest2函數可讀性增加了。
反彙編目标檔案的特定機器碼段:
[root@localhost test]# objdump -d mytest.o
mytest.o: file format elf32-i386
Disassembly of section .text:
00000000 <_Z9printTestv>:
0: 55 push %ebp
1: 89 e5 mov %esp,%ebp
3: 83 ec 10 sub $0x10,%esp
6: c6 45 ff 61 movb $0x61,0xffffffff(%ebp)
a: c9 leave
b: c3 ret
0000000c <_Z10printTest2v>:
c: 55 push %ebp
d: 89 e5 mov %esp,%ebp
f: 83 ec 10 sub $0x10,%esp
12: c7 45 fc 02 00 00 00 movl $0x2,0xfffffffc(%ebp)
19: 83 45 fc 02 addl $0x2,0xfffffffc(%ebp)
1d: c9 leave
1e: c3 ret
這裡,對text段的内容進行了反彙編。
反彙編特定段,并将彙編代碼對應的檔案名稱和行号對應上:
[root@localhost test]# objdump -d -l mytest.o
mytest.o: file format elf32-i386
Disassembly of section .text:
00000000 <_Z9printTestv>:
_Z9printTestv():
/root/test/04_libraryTest/mytest.cpp:1
0: 55 push %ebp
1: 89 e5 mov %esp,%ebp
3: 83 ec 10 sub $0x10,%esp
/root/test/04_libraryTest/mytest.cpp:4
6: c6 45 ff 61 movb $0x61,0xffffffff(%ebp)
/root/test/04_libraryTest/mytest.cpp:5
a: c9 leave
b: c3 ret
0000000c <_Z10printTest2v>:
_Z10printTest2v():
/root/test/04_libraryTest/mytest.cpp:6
c: 55 push %ebp
d: 89 e5 mov %esp,%ebp
f: 83 ec 10 sub $0x10,%esp
/root/test/04_libraryTest/mytest.cpp:8
12: c7 45 fc 02 00 00 00 movl $0x2,0xfffffffc(%ebp)
/root/test/04_libraryTest/mytest.cpp:9
19: 83 45 fc 02 addl $0x2,0xfffffffc(%ebp)
/root/test/04_libraryTest/mytest.cpp:10
1d: c9 leave
1e: c3 ret
這裡,項"-d"從objfile中反彙編那些特定指令機器碼的section,而使用"-l"指定用檔案名和行号标注相應的目标代碼,僅僅和-d、-D或者-r一起使用,使用-ld和使用-d的差別不是很大,在源碼級調試的時候有用,要求編譯時使用了-g之類的調試編譯選項。
顯示目标檔案各個段的頭部摘要資訊:
[root@localhost test]# objdump -h mytest.o
mytest.o: file format elf32-i386
Sections:
Idx Name Size VMA LMA File off Algn
0 .text 0000001f 00000000 00000000 00000034 2**2
CONTENTS, ALLOC, LOAD, readonly, CODE
1 .data 00000000 00000000 00000000 00000054 2**2
CONTENTS, ALLOC, LOAD, DATA
2 .bss 00000000 00000000 00000000 00000054 2**2
ALLOC
3 .debug_abbrev 00000046 00000000 00000000 00000054 2**0
CONTENTS, READONLY, DEBUGGING
4 .debug_info 000000ed 00000000 00000000 0000009a 2**0
CONTENTS, RELOC, READONLY, DEBUGGING
5 .debug_line 0000003e 00000000 00000000 00000187 2**0
CONTENTS, RELOC, READONLY, DEBUGGING
6 .debug_frame 00000044 00000000 00000000 000001c8 2**2
CONTENTS, RELOC, READONLY, DEBUGGING
7 .debug_loc 00000058 00000000 00000000 0000020c 2**0
CONTENTS, READONLY, DEBUGGING
8 .debug_pubnames 0000002f 00000000 00000000 00000264 2**0
CONTENTS, RELOC, READONLY, DEBUGGING
9 .debug_aranges 00000020 00000000 00000000 00000293 2**0
CONTENTS, RELOC, READONLY, DEBUGGING
10 .comment 0000002e 00000000 00000000 000002b3 2**0
CONTENTS, READONLY
11 .note.GNU-stack 00000000 00000000 00000000 000002e1 2**0
CONTENTS, READONLY
這裡,更多的内容參見
man objdump
中的這個選項。