一天一個 Linux 命令:objdump 命令

2021-03-02 Linux研習社
1.功能簡介

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

相關焦點

  • 每天一個 Linux 命令(106):objdump 命令
    1.功能簡介objdump 命令是 GNU Binutils 二進位工具集的一員,用於查看目標文件或可執行文件的組成信息,以可讀的形式列印二進位文件的內容。效果等同於命令 ar -tv-b, --target=BFDNAME 指定目標碼格式。這不是必須的,objdump 能自動識別許多格式,比如 objdump -b oasys -m vax -h fu.o 顯示 fu.o 的頭部摘要信息,明確指出該文件是 Vax 系統下用 Oasys 編譯器生成的目標文件。
  • 一天一個 Linux 命令: ldd 命令
    轉自:戀貓大鯉魚blog.csdn.net/K346K346/article/details/890621631.命令簡介ldd 命令用於列印程序或者共享庫文件所依賴的共享庫列表。注意,ldd 本身不是一個二進位程序,而是一個 Shell 腳本,使用文本編輯器 vim 可以查看其內容,具體目錄可以使用 which 命令查看:我們知道,Linux 的動態庫裝載器 ld-linux.so 模塊會先於 executable 模塊工作,並獲得控制權,ld-linux.so 會通過系統環境變量的設置,選擇只顯示可執行模塊的dependency
  • 每天一個 Linux 命令(49):at命令
    通過'添加任務計劃'的一步步引導,則可建立一個定時執行的任務。在linux系統中你可能已經發現了為什麼系統常常會自動的進行一些任務?這些任務到底是誰在支配他們工作的?在linux系統如果你想要讓自己設計的備份程序可以自動在某個時間點開始在系統底下運行,而不需要手動來啟動它,又該如何處置呢? 這些例行的工作可能又分為一次性定時工作與循環定時工作,在系統內又是哪些服務在負責?
  • 學習一個 Linux 命令: ldd 命令
    ldd 命令用於列印程序或者共享庫文件所依賴的共享庫列表。注意,ldd 本身不是一個二進位程序,而是一個 Shell 腳本,使用文本編輯器 vim 可以查看其內容,具體目錄可以使用 which 命令查看:我們知道,Linux 的動態庫裝載器 ld-linux.so 模塊會先於 executable 模塊工作,並獲得控制權,ld-linux.so 會通過系統環境變量的設置,選擇只顯示可執行模塊的dependency
  • 一天一個 Linux 命令: uptime 命令
    無選項 uptime 命令會顯示一行信息,依次為:當前時間、系統已經運行了多長時間、目前有多少用戶登錄、系統在過去的 1 分鐘、5 分鐘和 15 分鐘內的平均負載。輸出結果等同於 top 命令匯總區的第一行。
  • 每天一個 Linux 命令(111):ipcs 命令
    ipcs 命令用於查看 Linux 進程間通信設施的狀態,包括消息列表、共享內存和信號量的信息。注意,本文描述的是 util-linux 版 ipcs,和其它版本(如 POSIX 版)的實現可能會有出入。
  • 每天一個Linux命令(1):ls命令
    linux下最常用的命令。ls命令就是list的縮寫,預設下ls用來列印出當前目錄的清單。如果ls指定其他目錄,那麼就會顯示指定目錄裡的文件及文件夾清單。 通過ls 命令不僅可以查看linux文件夾包含的文件而且可以查看文件權限(包括目錄、文件夾、文件權限)查看目錄信息等等。ls 命令在日常的linux操作中用的很多!1.
  • 每天一個 Linux 命令(45):free 命令
    在Linux系統監控的工具中,free命令是最經常使用的命令之一。1.命令格式:free [參數]2.命令功能:free 命令顯示系統使用和空閒的內存情況,包括物理內存、交互區內存(swap)和內核緩衝區內存。
  • 每天一個 Linux 命令(50):crontab命令
    at 命令是針對僅運行一次的任務,循環運行的例行性計劃任務,linux系統則是由 cron (crond) 這個系統服務來控制的。一、crond簡介crond是linux下用來周期性的執行某種任務或等待處理某些事件的一個守護進程,與windows下的計劃任務類似,當安裝完成作業系統後,默認會安裝此服務工具,並且會自動啟動crond進程,crond進程每分鐘會定期檢查是否有要執行的任務,如果有要執行的任務,則自動執行該任務。
  • 每天一個 Linux 命令(44):top命令
    納入內核管理的內存不見得都在使用中,還包括過去使用過的現在可以被重複利用的內存,內核並不把這些可被重新使用的內存交還到free中去,因此在linux上free內存會越來越少,但不用為此擔心。這些命令都是單字母的,如果在命令行中使用了s 選項, 其中一些命令可能會被屏蔽。h 顯示幫助畫面,給出一些簡短的命令總結說明k 終止一個進程。i 忽略閒置和僵死進程。這是一個開關式命令。
  • 每天攻克一個linux命令:cp 命令
    Linux為我們提供了兩個用於文件copy的命令,一個是cp,一個是scp,但是他們略有不同。
  • 每天一個 Linux 命令(40):wc命令
    1.命令格式:wc [選項]文件...2.命令功能:統計指定文件中的字節數、字數、行數,並將統計結果顯示輸出。該命令統計指定文件中的字節數、字數、行數。如果沒有給出文件名,則從標準輸入讀取。wc同時也給出所指定文件的總統計數。
  • 每天一個linux命令(6):rmdir 刪除空文件目錄
    工欲善其事,必先利其器,提高效率,唯手熟爾。
  • 【linux】常用命令之scp命令
    今天需要在兩個伺服器之間進行數據copy,但是居然忘了linux命令,於是這裡記錄下,加深記憶!linux命令之scp命令用於linux之間文件或者目錄的複製。scp的全稱為secure copy,是基於ssh登錄進行安全的遠程文件或目錄copy命令,當然只能用於linux系統之間。
  • 每天一個 Linux 命令(52):ifconfig命令
    ssh登陸linux伺服器操作要小心,關閉了就不能開啟了,除非你有多網卡。本系列文章:每天一個 Linux 命令(1):ls命令每天一個 Linux 命令(2):cd命令每天一個 Linux 命令(3):pwd命令每天一個 Linux 命令(4):mkdir命令每天一個 Linux 命令(5):rm 命令每天一個 Linux 命令(6):rmdir 命令每天一個 Linux
  • 每天一個 Linux 命令(100):strings 命令
    strings 命令是二進位工具集 GNU Binutils 的一員,用於列印文件中可列印字符串,文件可以是文本文件(test.c),但一般用於列印二進位目標文件、庫或可執行文件中的可列印字符。strings /bin/ls/lib64/ld-linux-x86-64.so.2libselinux.so.1_ITM_deregisterTMCloneTable__gmon_start___Jv_RegisterClasses_ITM_registerTMCloneTable
  • 每天一個 Linux 命令(13):less 命令
    ↓推薦關注↓less 工具也是對文件或其它輸出進行分頁顯示的工具,應該說是 linux
  • 每天一個 Linux 命令(35):top 命令
    top命令是 Linux 下常用的性能分析工具,能夠實時顯示系統中各個進程的資源佔用狀況,類似於 Windows 的任務管理器。下面詳細介紹它的使用方法。top 是一個動態顯示過程,即可以通過用戶按鍵來不斷刷新當前狀態。
  • 每天一個 Linux 命令(40):ifconfig 命令
    許多 windows 非常熟悉 ipconfig 命令行工具,它被用來獲取網絡接口配置信息並對此進行修改。Linux 系統擁有一個類似的工具,也就是 ifconfig(interfaces config)。
  • 每天一個 Linux 命令(104):strip 命令
    此選項可能不止一次      [-w|--wildcard]:允許在其他命令行選項中對符號名稱使用正則表達式。問號(?)使用此參數時,只能指定一個objfile      [-p|--preserve-dates]:保留文件的訪問和修改日期      [-D|--enable-deterministic-archives]:以確定性模式(deterministic mode)操作。