objdump 命令是 GNU Binutils 二進位工具集的一員,用於查看目標文件或可執行文件的組成信息,以可讀的形式列印二進位文件的內容。
2.命令格式objdump [OPTIONS] OBJFILES
3.選項說明-a, --archive-headers
顯示檔案頭信息,展示檔案每一個成員的文件格式。效果等同於命令 ar -tv
-b, --target=BFDNAME
指定目標碼格式。這不是必須的,objdump 能自動識別許多格式,比如 objdump -b oasys -m vax -h fu.o 顯示 fu.o 的頭部摘要信息,明確指出該文件是 Vax 系統下用 Oasys 編譯器生成的目標文件。objdump -i 將給出這裡可以指定的目標碼格式列表
-C, --demangle[=STYLE]
目標文件中的符號解碼成用戶級名稱。比如移除符號修飾時在變量與函數名前添加的下劃線等。
-d, --disassemble
反彙編目標文件,將機器指令反彙編成彙編代碼
-D, --disassemble-all
與 -d 類似,但反彙編所有段(section)
-z, --disassemble-zeroes
一般反彙編輸出將省略零塊,該選項使得這些零塊也被反彙編
-EB, -EL,--endian={big | little}
指定目標文件的字節序,在目標文件沒描述字節序時很有用,例如 S-records。這個選項只影響反彙編
-f, --file-headers
顯示每一個目標文件的頭信息
-F, --file-offsets
反彙編時,列印每一個符號的偏移地址
--file-start-context
顯示源碼/彙編代碼(假設為 -S)時,將上下文擴展到文件的開頭
-g, --debugging
顯示調試信息。企圖解析保存在文件中的調試信息並以 C 語言的語法顯示出來。僅僅支持某些類型的調試信息。有些其他的格式被readelf -w支持
-e, --debugging-tags
類似 -g 選項,但是生成的信息是和ctags工具相兼容的格式
-h, --section-headers, --headers
顯示目標文件各個 section 的頭部摘要信息
-i, --info
顯示對於 -b 或者 -m 選項可用的架構和目標格式列表
-j, --section=NAME
僅顯示指定名稱的 section 的信息
-l, --line-numbers
用文件名和行號標註相應的目標代碼,僅僅和 -d、-D 或者 -r 一起使用
-S,--source
反彙編時儘可能使用原始碼表示。隱含了-d參數
-m, --architecture=MACHINE
指定反彙編目標文件時使用的架構,當待反彙編文件本身沒描述架構信息的時候(比如S-records),這個選項很有用。可以用-i選項列出這裡能夠指定的架構
-M, --disassembler-options=OPTIONS
給反彙編程序傳遞參數,可以指定多個,使用逗號分隔
-p, --private-headers
列印目標文件格式的特定信息。列印的信息取決於目標文件格式,對於某些目標文件格式,不列印任何附加信息。
-P, --private=OPTIONS
列印目標文件格式的特定信息。OPTIONS 是一個逗號分隔的列表。例如對於XCOFF,可用的選項有 header, aout, sections, syms, relocs, lineno, loader, except, typchk, traceback and toc
-r, --reloc
顯示文件的重定位入口。如果和-d或者-D一起使用,重定位部分以反彙編後的格式顯示出來
-R, --dynamic-reloc
顯示文件的動態重定位入口,僅僅對於動態目標文件意義,比如某些共享庫
-s, --full-contents
顯示section的完整內容。默認所有的非空section都會被顯示
-W[lLiaprmfFsoRt],--dwarf=[rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,=frames-interp,=str,=loc,=Ranges,=pubtypes,=trace_info,=trace_abbrev,=trace_aranges,=gdb_index]
顯示文件中調試段的內容,如果存在的話
-G, --stabs
顯示請求的任何 section 的全部內容。顯示段 .stab、.stab.index 和 .stab.excl 的內容
-t, --syms
顯示文件的符號表入口。類似於nm -s提供的信息
-T, --dynamic-syms
顯示文件的動態符號表入口,僅僅對動態目標文件意義,比如某些共享庫。它顯示的信息類似於 nm -D,--dynamic 顯示的信息
-x, --all-headers
顯示所可用的頭信息,包括符號表、重定位入口。-x 等價於 -a -f -h -p -r -t 同時指定
-w, --wide
為具有超過80列的輸出設備格式化某些行。也不要在顯示符號名稱時截斷符號名稱
--start-address=ADDRESS
從指定地址開始顯示數據,該選項影響 -d、-r 和 -s 選項的輸出
--stop-address=ADDRESS
顯示數據直到指定地址為止,該項影響-d、-r和-s選項的輸出
--prefix-addresses
反彙編的時候,顯示每一行的完整地址。這是一種比較老的反彙編格式
--no-show-raw-insn
反彙編時,不顯示彙編指令的機器碼。當使用--prefix-addresses時,這是預設選項
--adjust-vma=OFFSET
當解析信息時,首先給所有的段添加偏移值offset。當段地址與符號表不符時,這個選項很有用。比如將段放置到特殊地址,因為某個格式無法表示段地址,比如 a.out
--special-syms
顯示特殊符號與用戶不關心的符號
--prefix=PREFIX
當使用 -S 時,指定前綴添加到絕對路徑中
--prefix-strip=LEVEL
指定剝離絕對路徑中多少個前綴目錄名。此選項只有在使用了選項 --prefix=PREFIX 才有效
--insn-width=WIDTH
指定反彙編後的指令輸出的行寬,單位字節
-V, --version
版本信息
-H, --help
幫助信息
4.常用示例首先給出後面大部分測試所基於的原始碼以及編譯指令。涉及兩個 C++ 源文件。
objdump.cpp:#include <iostream>
void print()
{
std::cout<<"objdump"<<std::endl;
}main.cpp:
#include <iostream>
using namespace std;
void print();
int main()
{
print();
}使用-g選項加入調試信息,分別編譯生成目標文件objdump.o與main.o。
g++ -c -g objdump.cpp -o objdump.o
g++ -c -g main.cpp -o main.o然後通過ar命令將兩個目標文件打包成靜態庫libobjdump.a。
ar crv libobjdump.a main.o objdump.o(1)查看檔案包含的目標文件列表。
[root@TENCENT64 ~]# objdump -a libobjdump.a
In archive libobjdump.a:
main.o: file format elf64-x86-64
rw-r--r-- 0/0 18696 Mar 8 20:25 2019 main.o
objdump.o: file format elf64-x86-64
rw-r--r-- 0/0 21352 Mar 8 20:25 2019 objdump.o使用命令ar -tv也可以列出檔案中包含的目標文件。
[root@TENCENT64 ~]# ar -tv libobjdump.a
rw-r--r-- 0/0 18696 Mar 8 20:25 2019 main.o
rw-r--r-- 0/0 21352 Mar 8 20:25 2019 objdump.o(2)顯示目標文件objdump.o的代碼段(.text)內容。
[root@TENCENT64 ~]# objdump --section=.text -s objdump.o
objdump.o: file format elf64-x86-64
Contents of section .text:
0000 554889e5 be000000 00bf0000 0000e800 UH....
0010 000000be 00000000 4889c7e8 00000000 ...H..
0020 5dc35548 89e54883 ec10897d fc8975f8 ].UH..H....}..u.
0030 837dfc01 7527817d f8ffff00 00751ebf .}..u'.}u..
0040 00000000 e8000000 00ba0000 0000be00 .
0050 000000bf 00000000 e8000000 00c9c355 U
0060 4889e5be ffff0000 bf010000 00e8b0ff H
0070 ffff5dc3 ..].注意,不能單獨使用-j或者–section選項,一定要加上-s選項。
(3)反彙編objdump.o中的text段內容,並儘可能用原始碼形式表示。
[root@TENCENT64 ~]# objdump --section=.text -S objdump.o
objdump.o: file format elf64-x86-64
Disassembly of section .text:
0000000000000000 <_Z5printv>:
#include <iostream>
void print()
{
0: 55 push %rbp
1: 48 89 e5 mov %rsp,%rbp
std::cout<<"objdump"<<std::endl;
4: be 00 00 00 00 mov $0x0,%esi
9: bf 00 00 00 00 mov $0x0,%edi
e: e8 00 00 00 00 callq 13 <_Z5printv+0x13>
13: be 00 00 00 00 mov $0x0,%esi
18: 48 89 c7 mov %rax,%rdi
1b: e8 00 00 00 00 callq 20 <_Z5printv+0x20>
}
20: 5d pop %rbp
21: c3 retq
0000000000000022 <_Z41__static_initialization_and_destruction_0ii>:
22: 55 push %rbp
23: 48 89 e5 mov %rsp,%rbp
26: 48 83 ec 10 sub $0x10,%rsp
2a: 89 7d fc mov %edi,-0x4(%rbp)
2d: 89 75 f8 mov %esi,-0x8(%rbp)
30: 83 7d fc 01 cmpl $0x1,-0x4(%rbp)
34: 75 27 jne 5d <_Z41__static_initialization_and_destruction_0ii+0x3b>
36: 81 7d f8 ff ff 00 00 cmpl $0xffff,-0x8(%rbp)
3d: 75 1e jne 5d <_Z41__static_initialization_and_destruction_0ii+0x3b>
extern wostream wclog; /// Linked to standard error (buffered)
#endif
//@}
// For construction of filebuffers for cout, cin, cerr, clog et. al.
static ios_base::Init __ioinit;
3f: bf 00 00 00 00 mov $0x0,%edi
44: e8 00 00 00 00 callq 49 <_Z41__static_initialization_and_destruction_0ii+0x27>
49: ba 00 00 00 00 mov $0x0,%edx
4e: be 00 00 00 00 mov $0x0,%esi
53: bf 00 00 00 00 mov $0x0,%edi
58: e8 00 00 00 00 callq 5d <_Z41__static_initialization_and_destruction_0ii+0x3b>
5d: c9 leaveq
5e: c3 retq
000000000000005f <_GLOBAL__sub_I__Z5printv>:
5f: 55 push %rbp
60: 48 89 e5 mov %rsp,%rbp
63: be ff ff 00 00 mov $0xffff,%esi
68: bf 01 00 00 00 mov $0x1,%edi
6d: e8 b0 ff ff ff callq 22 <_Z41__static_initialization_and_destruction_0ii>
72: 5d pop %rbp
73: c3 retq(3)顯示目標文件的符號表入口。
[root@TENCENT64 ~]# objdump -t objdump.o
objdump.o: file format elf64-x86-64
SYMBOL TABLE:
0000000000000000 l df *ABS* 0000000000000000 objdump.cpp
0000000000000000 l d .text 0000000000000000 .text
0000000000000000 l d .data 0000000000000000 .data
0000000000000000 l d .bss 0000000000000000 .bss
0000000000000000 l O .bss 0000000000000001 _ZStL8__ioinit
0000000000000000 l d .rodata 0000000000000000 .rodata
0000000000000022 l F .text 000000000000003d _Z41__static_initialization_and_destruction_0ii
000000000000005f l F .text 0000000000000015 _GLOBAL__sub_I__Z5printv
0000000000000000 l d .init_array 0000000000000000 .init_array
0000000000000000 l d .debug_info 0000000000000000 .debug_info
0000000000000000 l d .debug_abbrev 0000000000000000 .debug_abbrev
0000000000000000 l d .debug_aranges 0000000000000000 .debug_aranges
0000000000000000 l d .debug_line 0000000000000000 .debug_line
0000000000000000 l d .debug_str 0000000000000000 .debug_str
0000000000000000 l d .note.GNU-stack 0000000000000000 .note.GNU-stack
0000000000000000 l d .eh_frame 0000000000000000 .eh_frame
0000000000000000 l d .comment 0000000000000000 .comment
0000000000000000 g F .text 0000000000000022 _Z5printv
0000000000000000 *UND* 0000000000000000 _ZSt4cout
0000000000000000 *UND* 0000000000000000 _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc
0000000000000000 *UND* 0000000000000000 _ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_
0000000000000000 *UND* 0000000000000000 _ZNSolsEPFRSoS_E
0000000000000000 *UND* 0000000000000000 _ZNSt8ios_base4InitC1Ev
0000000000000000 *UND* 0000000000000000 .hidden __dso_handle
0000000000000000 *UND* 0000000000000000 _ZNSt8ios_base4InitD1Ev
0000000000000000 *UND* 0000000000000000 __cxa_atexit這裡,輸出的信息類似nm -s命令的輸出,相比較之下,nm命令的輸出如下:
[root@TENCENT64 ~]# nm -s objdump.o
U __cxa_atexit
U __dso_handle
000000000000005f t _GLOBAL__sub_I__Z5printv
0000000000000022 t _Z41__static_initialization_and_destruction_0ii
0000000000000000 T _Z5printv
U _ZNSolsEPFRSoS_E
U _ZNSt8ios_base4InitC1Ev
U _ZNSt8ios_base4InitD1Ev
U _ZSt4cout
U _ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_
0000000000000000 b _ZStL8__ioinit
U _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc(4)顯示目標文件各個段的頭部摘要信息。
[root@TENCENT64 ~]# objdump -h objdump.o
objdump.o: file format elf64-x86-64
Sections:
Idx Name Size VMA LMA File off Algn
0 .text 00000074 0000000000000000 0000000000000000 00000040 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
1 .data 00000000 0000000000000000 0000000000000000 000000b4 2**2
CONTENTS, ALLOC, LOAD, DATA
2 .bss 00000001 0000000000000000 0000000000000000 000000b4 2**2
ALLOC
3 .rodata 00000008 0000000000000000 0000000000000000 000000b4 2**0
CONTENTS, ALLOC, LOAD, READONLY, DATA
4 .init_array 00000008 0000000000000000 0000000000000000 000000c0 2**3
CONTENTS, ALLOC, LOAD, RELOC, DATA
5 .debug_info 000014f9 0000000000000000 0000000000000000 000000c8 2**0
CONTENTS, RELOC, READONLY, DEBUGGING
6 .debug_abbrev 0000039f 0000000000000000 0000000000000000 000015c1 2**0
CONTENTS, READONLY, DEBUGGING
7 .debug_aranges 00000030 0000000000000000 0000000000000000 00001960 2**0
CONTENTS, RELOC, READONLY, DEBUGGING
8 .debug_line 00000244 0000000000000000 0000000000000000 00001990 2**0
CONTENTS, RELOC, READONLY, DEBUGGING
9 .debug_str 00000e4c 0000000000000000 0000000000000000 00001bd4 2**0
CONTENTS, READONLY, DEBUGGING
10 .comment 0000002d 0000000000000000 0000000000000000 00002a20 2**0
CONTENTS, READONLY
11 .note.GNU-stack 00000000 0000000000000000 0000000000000000 00002a4d 2**0
CONTENTS, READONLY
12 .eh_frame 00000078 0000000000000000 0000000000000000 00002a50 2**3
CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA
參考文獻[1] objdump manual
[2] objdump命令.Linux命令大全
[3] GNU Binutils