ELF文件基礎


ELF (Executable Linkable Format,wiki  chs)是Linux參考COFF(Common Object File Format)規范而定義的可執行文件格式。

可執行文件、共享目標文件(*.so)、目標中間文件(又稱可重定位文件,*.o)、核心轉儲文件(Core Dump File)都是ELF文件。

按位數可分為:elf32和elf64;支持cpu架構有:aarch64(即:arm64)、arm等。

ELF可能按照不同的字節序(Byte Order)來存儲。例如:elf32-bigarm是大端(Big-endian)存儲;elf64-littleaarch64是小端(Little-endian)存儲。

與COFF一樣,ELF也是基於段(Segment,有時也被叫節Section)的結構。其文件結構如下:

 

ELF頭(ELF Header):ELF魔數、文件機器字節長度、數據存儲方式(大小端)、版本、運行平台、ABI版本、ELF重定位類型、硬件平台及版本、入口地址、程序頭入口和長度、段表的位置和長度、段的數量。

段表(Section header table):描述了ELF各個段的基本信息,如:每個段的段名、段的長度、在文件中偏移、讀寫權限及段的其他屬性。編譯器、鏈接器和裝載器都是依靠段表來定位和訪問各個段的屬性的。

 

段的類型

常量 含義
SHT_NULL 0 無效段
SHT_PROGBITS 1 程序段、代碼段、數據段都是這種類型
SHT_SYMTAB 2 該段的內容為符號表
SHT_STRTAB 3 該段的內容為字符串表
SHT_RELA 4 重定位表,包含重定位信息
SHT_HASH 5 符號表的哈希表
SHT_DYNAMIC 6 動態鏈接信息
SHT_NOTE 7 提示性信息
SHT_NOBITS 8 表示該段在文件中沒有內容。如:bss段
SHT_REL 9 該段包含了重定位信息
SHT_SHLIB 10 保留
SHT_DNYSYM 11 動態鏈接的符號表

段的標志位表示該段在進程虛擬空間中的屬性。包括:是否可寫(SHF_WRITE),是否需要分配空間(SHF_ALLOC)及是否可執行(SHF_EXECINSTR)。

 

常見的段如下:

段名 類型 標志位 說明
.text SHT_PROGBITS

SHF_ALLOC + SHF_EXECINSTR

代碼段

 

存放程序的可執行代碼

.data

.data1

SHT_PROGBITS

SHF_ALLOC + SHF_EXECINSTR

數據段

 

存放如下內容:

① 顯示初始化為非0的局部靜態變量

② 顯示初始化為非0的全局變量

.rela.text

.rel.text

SHT_RELA  

代碼段重定位表

 

存在於目標中間文件(又稱可重定位文件,*.o)中,用於鏈接時重定位(為靜態重定位)

.rela.data

.rel.data

SHT_RELA  

數據段重定位表

 

存在於目標中間文件(又稱可重定位文件,*.o)中,用於鏈接時重定位(為靜態重定位)

.rodata

.rodata1

SHT_PROGBITS

SHF_ALLOC

只讀數據段

 

存放如下內容:

① 字符串常量

② 全局const變量

.bss SHT_NOBITS

SHF_ALLOC + SHF_WRITE

bss段

這個段在程序運行時,在內存中會被清零

在ELF文件中不占用空間

 

存放如下內容:

① 未初始化的全局變量

② 未初始化的局部靜態變量

③ 顯示初始化為0的局部靜態變量

④ 顯示初始化為0的全局變量

.tdata   SHF_ALLOC + SHF_WRITE

用來保存線程局部存儲的初始化數據。

默認情況下,每次進程啟動新的線程時,系統會產生一份.tdata副本。

.tbss   SHF_ALLOC + SHF_WRITE

用來保存線程局部存儲的未初始化數據。

默認情況下,每次進程啟動新的線程時,系統會產生一份.tbss副本,並將它的內容初始化為0。

.data.rel.ro   SHF_ALLOC(SHF_WRITE) 保存的是程序的只讀數據,與.rodata類似,唯一不同的是它在重定位時會被改寫,然后將會被置為只讀。
.dynamic SHT_DYNAMIC

SHF_ALLOC + SHF_WRITE

注:在某些系統,可能是只讀的,沒有SHF_WRITE標志位

動態鏈接信息

 

① 依賴於哪些共享對象

② 動態鏈接符號表(.dynsym)的位置

③ 動態鏈接重定位表(.rela.dyn)的位置

④ 共享對象初始化代碼的地址

.plt   SHF_ALLOC + SHF_EXECINSTR

用於支持延遲綁定,這些指令是用來計算外部函數的最終地址

.got   SHF_ALLOC + SHF_WRITE

全局偏移表 (Global Offset Table,GOT)

存放外部變量的地址

 

GOT表中的地址需要動態鏈接器在裝載模塊,進行地址重定位時進行填充。

在訪問外部符號,可以先通過相對地址找到GOT表中相關的項,再從中取出最終地址

.got.plt   SHF_ALLOC + SHF_WRITE

使用PLT(Procedure Linkage Table,過程鏈接表)來實現對外部函數延遲綁定(第一次用到時才進行綁定)

以此來提升程序的啟動速度

 

第一項保存的是“.dynamic”段的地址
第二項保存的是本模塊的ID
第三項保存的是_dl_runtime_resolve()的地址

第N項保存的是運用plt段的指令計算得到的外部函數的最終地址(動態鏈接器重定位得到外部函數的地址后,會寫入在這里)

.rela.dyn

.rel.dyn

SHT_RELA SHF_ALLOC

.dynsym段的重定位表

 

對數據引用的修正,它所修正的位置存放在“.got”以及數據段

.rela.plt

.rel.plt

SHT_RELA SHF_ALLOC

.plt段的重定位表

對函數引用的修正,它所修正的位置存放在“.got.plt”

.dynstr   SHF_ALLOC

動態符號字符串表(Dynamic String Table)

 

存放動態鏈接符號的符號名

.dynsym   SHF_ALLOC

動態符號表(Dynamic Symbol Table)

 

① 導入符號(Import Symbol)

② 導出符號(Export Symbol)

 

編譯選項開啟:-fvisibility=hidden -fvisibility-inlines-hidden,默認不導出so中的符號

.hash SHT_HASH

SHF_ALLOC 

動態符號哈希表

 

提升動態符號的查找效率

.comment SHT_PROGBITS

 

注釋信息段 

 

存放的是編譯器版本信息,比如字符串:"GCC:(GNU)4.2.0"

.init   SHF_ALLOC + SHF_EXECINSTR

程序執行前的初始化代碼,這些代碼早於main函數被執行,多數被用作實現C++全局構造

.fini   SHF_ALLOC + SHF_EXECINSTR 程序退出時執行的代碼,這些代碼晚於main函數執行,多數被用作實現C++全局析構
.init_array SHT_PROGBITS

SHF_ALLOC + SHF_EXECINSTR

包含一些程序或共享對象剛開始初始化時所須要執行的函數指針

.fini_array SHT_PROGBITS SHF_ALLOC + SHF_EXECINSTR 包含一些程序或共享對象退出時須要執行的函數指針
.preinit_array     保存的是早於初始化階段執行的函數指針數組,這些函數會在.init_array的函數指針數組之前被執行
.ctors    

保存的是全局構造函數指針

.dtors    

保存的是全局析構函數指針

.interp SHT_PROGBITS  

包含動態鏈接器的路徑(如:/lib/ld-linux.so.2)

interp是interpreter(解釋器)的縮寫

 

系統在對可執行文件進行加載時,會從該段尋找並裝載該可執行文件所需的動態鏈接器。

.shstrtab SHT_STRTAB  

段表字符串表(Section String Table)

用於存放各個段的名字

.note.GNU-stack SHT_NOTE   堆棧提示段
.note.android.ide SHT_NOTE   記錄使用的android ndk的版本
.note.gnu.build-id SHT_NOTE   鏈接時的唯一標識
.note.ABI-tag SHT_NOTE   指定程序的ABI
.eh_frame SHT_PROGBITS  

c++異常處理相關的內容   詳見:Exception Frames

 

異常時棧幀unwind信息(Exception Handling Frame unwinding information)

Call Frame Information(CFI)信息,保存了函數的調用關系,可以用於異常發生后的棧回溯

 

編譯時,帶上-funwind-tables,可以去除該段

-fno-asynchronous-unwind-tables

.eh_frame_hdr SHT_PROGBITS  

c++異常處理相關的內容

 

包含了對.eh_frame的補充信息

① 一個指針指向.eh_frame包含的數據起始地址
② 指向.eh_frame記錄的指針的二分查找表

.gcc_except_table SHT_PROGBITS   try catch異常處理相關的信息:如異常時的對象清理邏輯
.jcr     Java類注冊信息
.gnu.version    

符號版本相關

 

所有動態符號的版本信息,它和.dynsym是一一對應的

為0表示內部定義的local的符號,1表示內部定義的global符號

其他的值則來自於.gnu_version_d的Index和.gnu_version_r的Version,前者表示導出的符號版本信息,后者表示導入的符號版本信息

.gnu.version_d    

符號版本相關

 

版本定義信息

.gnu.version_r    

符號版本相關

.debug_str

.debug_loc

.debug_abbrev

.debug_info

.debug_ranges

.debug_macinfo

.debug_line

.debug_aranges

SHT_PROGBITS  

調試信息

 

ELF采用DWARF(Debug With Arbitrary Record Format)的標准調試信息格式來存放調試信息

.symtab SHT_SYMTAB 如果有其他裝載的段用到該段,則有SHF_ALLOC標志位

符號表(Symbol Table)

保存鏈接時所需要的符號信息

.strtab SHT_STRTAB 如果有其他裝載的段用到該段,則有SHF_ALLOC標志位

字符串表(String Table)

通常是符號表里的符號名所需要的字符串

 

注:目標中間文件(又稱可重定位文件,*.o)也存在該段

 

readelf

llvm-readelf.exe所在目錄在:<android-ndk>\toolchains\llvm\prebuilt\windows-x86_64\bin 

llvm-readelf.exe -S libUE4.so  // 輸出libUE4.so段表中各個段的信息

There are 27 section headers, starting at offset 0xf2c1650:

Section Headers:
  [Nr] Name              Type             Address           Offset     
       Size              EntSize          Flags  Link  Info  Align     ;Size為段的長度;Offset為段在文件中偏移位置
  [ 0]                   NULL             0000000000000000  00000000   ;第一個元素是無效的段描述符,類型為NULL
       0000000000000000  0000000000000000           0     0     0
  [ 1] .note.android.ide NOTE             0000000000000270  00000270   ;記錄使用的android ndk的版本的段
       0000000000000098  0000000000000000   A       0     0     4
  [ 2] .note.gnu.build-i NOTE             0000000000000308  00000308   ;鏈接時的唯一標識
       0000000000000024  0000000000000000   A       0     0     4
  [ 3] .dynsym           DYNSYM           0000000000000330  00000330
       0000000000dee838  0000000000000018   A       8     1     8
  [ 4] .gnu.version      VERSYM           0000000000deeb68  00deeb68
       000000000012935a  0000000000000002   A       3     0     2
  [ 5] .gnu.version_r    VERNEED          0000000000f17ec4  00f17ec4
       0000000000000080  0000000000000000   A       8     4     4
  [ 6] .gnu.hash         GNU_HASH         0000000000f17f48  00f17f48
       00000000003e61c8  0000000000000000   A       3     0     8
  [ 7] .hash             HASH             00000000012fe110  012fe110
       00000000004a4d70  0000000000000004   A       3     0     4
  [ 8] .dynstr           STRTAB           00000000017a2e80  017a2e80
       000000000326c716  0000000000000000   A       0     0     1
  [ 9] .rela.dyn         RELA             0000000004a0f598  04a0f598
       0000000001a9a510  0000000000000018   A       3     0     8
  [10] .rela.plt         RELA             00000000064a9aa8  064a9aa8
       00000000000041b8  0000000000000018  AI       3    22     8
  [11] .rodata           PROGBITS         00000000064adc80  064adc80   ; 只讀數據段
       0000000000b19d08  0000000000000000 AMS       0     0     64
  [12] .gcc_except_table PROGBITS         0000000006fc7988  06fc7988
       000000000005e32c  0000000000000000   A       0     0     4
  [13] .eh_frame_hdr     PROGBITS         0000000007025cb4  07025cb4
       00000000003aed74  0000000000000000   A       0     0     4
  [14] .eh_frame         PROGBITS         00000000073d4a28  073d4a28
       0000000000e29424  0000000000000000   A       0     0     8
  [15] .text             PROGBITS         00000000081fe000  081fe000   ; 代碼段
       0000000006464320  0000000000000000  AX       0     0     16
  [16] .plt              PROGBITS         000000000e662320  0e662320
       0000000000002bf0  0000000000000000  AX       0     0     16
  [17] .data.rel.ro      PROGBITS         000000000e665000  0e665000
       0000000000b40f88  0000000000000000  WA       0     0     16
  [18] .fini_array       FINI_ARRAY       000000000f1a5f88  0f1a5f88
       0000000000000010  0000000000000008  WA       0     0     8
  [19] .init_array       INIT_ARRAY       000000000f1a5f98  0f1a5f98
       0000000000002918  0000000000000008  WA       0     0     8
  [20] .dynamic          DYNAMIC          000000000f1a88b0  0f1a88b0
       00000000000002b0  0000000000000010  WA       8     0     8
  [21] .got              PROGBITS         000000000f1a8b60  0f1a8b60
       00000000000e3280  0000000000000000  WA       0     0     8
  [22] .got.plt          PROGBITS         000000000f28bde0  0f28bde0
       0000000000001600  0000000000000000  WA       0     0     8
  [23] .data             PROGBITS         000000000f28e000  0f28e000   ; 數據段
       0000000000033220  0000000000000000  WA       0     0     16
  [24] .bss              NOBITS           000000000f2c1240  0f2c1220   ; BSS段  該段在文件中不存在內容
       000000000060aaa8  0000000000000000  WA       0     0     64
  [25] .comment          PROGBITS         0000000000000000  0f2c1220   ; 注釋信息段
       0000000000000328  0000000000000001  MS       0     0     1
  [26] .shstrtab         STRTAB           0000000000000000  0f2c1548
       0000000000000104  0000000000000000           0     0     1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
  L (link order), O (extra OS processing required), G (group), T (TLS),
  C (compressed), x (unknown), o (OS specific), E (exclude),
  p (processor specific)

注:以上段的Offset是基於ELF文件起始處

 

以uam為例,libUE4.so的大小對比:

配置 so size debug so size
Debug 532MB 2.07GB
DebugGame 389MB 2.48GB
Development 343MB 2.52GB
Test 175MB 2.11GB
Shipping 148MB 1.81GB

注:對debug so執行strip -S命令去除掉調試信息,就得到so文件

 

不同配置的libUE4.so(非debug)各個段的大小對比(單位為byte): 

段名 Debug DebugGame Development Test Shipping
.note.android.ident 152 152 152 152 152
.note.gnu.build-id 36 36 36 36 36
.dynsym 36937800 21539400 19843704 391176 195792
.gnu.version 3078150 1794950 1653642 32598 16316
.gnu.version_r 128 128 128 128 128
.gnu.hash 11885344 6580208 6226960 110088 53272
.hash 12312608 7179808 6614576 130400 65272
.dynstr 166468508 88218683 81551149 854321 244190
.rela.dyn 35363208 34303248 34031904 29215536 27984648
.rela.plt 19488 19416 19320 18768 17760
.rodata 15322736 15091552 15056704 11529632 10449008
.gcc_except_table 554452 597372 662504 650196 544796
.eh_frame_hdr 13486636 6668844 5787516 3948092 3640124
.eh_frame 51114172 25550380 22173820 15188700 13873572
.text 194929800 184359724 150390280 107480476 84720920
.plt 13024 12976 12912 12544 11872
.data.rel.ro 14868208 14560768 14509008 13900256 13422608
.fini_array 16 16 16 16 16
.init_array 11432 11288 11288 11232 10320
.dynamic 736 736 736 736 736
.got 1234496 1196112 1189088 46504 34848
.got.plt 6520 6496 6464 6280 5944
.data 398160 276400 234256 161744 157440
.bss 6143992 6076552 6051080 5332728 4972416
.comment 747 747 747 747 747
.shstrtab 260 260 260 260 260

 

llvm-readelf.exe -t libUE4.so  // 輸出libUE4.so段表中各個段的信息

llvm-readelf.exe -h libUE4.so  // 輸出libUE4.so的ELF頭的信息

llvm-readelf.exe -l libUE4.so  // 輸出libUE4.so的program headers

llvm-readelf.exe -e libUE4.so  // 等價於-h -l -S輸出的信息

llvm-readelf.exe -d libUE4.so  // 輸出libUE4.so的dynamic段的信息

llvm-readelf.exe -r libUE4.so  // 輸出libUE4.so的重定位信息(.rela.dyn段和.rela.plt段)

llvm-readelf.exe --dyn-syms -d -C -W libUE4.so  // 輸出libUE4.so的dynsym段中所有符號(不截斷),且自動對c++符號名進行反修飾(Demangle),並輸出libUE4.so依賴的so文件  注:Ndx為UND時,表示是一個導入符號

。。。 。。。
 37263: 000000000a0cca50   144 FUNC    GLOBAL DEFAULT   15 uprv_stricmp_64
 37264: 000000000b1deeb8    56 OBJECT  GLOBAL DEFAULT   17 CMS_ReceiptRequest_it
 37265: 000000000a3efec4    16 FUNC    GLOBAL DEFAULT   15 hb_font_is_immutable
 37266: 0000000009f258f8   164 FUNC    GLOBAL DEFAULT   15 g6_toolkit_manager::LoginRsp::default_instance()
 37267: 0000000009ffdde4   164 FUNC    GLOBAL DEFAULT   15 G6ToolKit::google::protobuf::OneofOptions::default_instance()
 37268: 0000000002778899    18 OBJECT  GLOBAL DEFAULT   11 typeinfo name for icu_64::UObject
 37269: 000000000a3e8278    92 FUNC    GLOBAL DEFAULT   15 hb_segment_properties_equal
 37270: 000000000a462248    68 FUNC    GLOBAL DEFAULT   15 png_reciprocal
 37271: 0000000009a955b4   236 FUNC    GLOBAL DEFAULT   15 ak_rpmalloc_initialize
 37272: 0000000009edf7bc   388 FUNC    WEAK   DEFAULT   15 void physx::RepXPropertyFilter<physx::Sn::RepXVisitorWriter<physx::PxVehicleClutchData> >::operator()<588u, physx::PxVehicleClutchData, unsigned int, unsigned int>(physx::PxPropertyInfo<588u, physx::PxVehicleClutchData, unsigned int, unsigned int> const&, unsigned int)
 37273: 000000000a0070b4    56 FUNC    GLOBAL DEFAULT   15 G6ToolKit::google::protobuf::SourceCodeInfo_Location::CopyFrom(G6ToolKit::google::protobuf::SourceCodeInfo_Location const&)
 37274: 000000000a32976c    36 FUNC    GLOBAL DEFAULT   15 d2i_RSA_PUBKEY_bio
Dynamic section at offset 0xb211b58 contains 52 entries:
  Tag                Type                 Name/Value
  0x0000000000000001 (NEEDED) Shared library: [libGLESv3.so] 0x0000000000000001 (NEEDED) Shared library: [libEGL.so] 0x0000000000000001 (NEEDED) Shared library: [libandroid.so] 0x0000000000000001 (NEEDED) Shared library: [libOpenSLES.so] 0x0000000000000001 (NEEDED) Shared library: [libc.so] 0x0000000000000001 (NEEDED) Shared library: [libdl.so] 0x0000000000000001 (NEEDED) Shared library: [liblog.so] 0x0000000000000001 (NEEDED) Shared library: [libm.so] 0x0000000000000001 (NEEDED) Shared library: [libz.so] 0x0000000000000001 (NEEDED) Shared library: [libTDataMaster.so] 0x0000000000000001 (NEEDED) Shared library: [libMSDKCore.so] 0x0000000000000001 (NEEDED) Shared library: [libGPM.so] 0x0000000000000001 (NEEDED) Shared library: [libgrobot.so] 0x0000000000000001 (NEEDED) Shared library: [libavcodec.so] 0x0000000000000001 (NEEDED) Shared library: [libavfilter.so] 0x0000000000000001 (NEEDED) Shared library: [libavformat.so] 0x0000000000000001 (NEEDED) Shared library: [libavutil.so] 0x0000000000000001 (NEEDED) Shared library: [libswresample.so] 0x0000000000000001 (NEEDED) Shared library: [libswscale.so] 0x0000000000000001 (NEEDED) Shared library: [libgcloudcore.so] 0x0000000000000001 (NEEDED) Shared library: [libgcloud.so] 0x0000000000000001 (NEEDED) Shared library: [libhttpdns.so] 0x0000000000000001 (NEEDED) Shared library: [libHttpDnsPlugin.so] 0x0000000000000001 (NEEDED) Shared library: [libtersafe.so] 0x0000000000000001 (NEEDED) Shared library: [libGVoice.so] 0x0000000000000001 (NEEDED) Shared library: [libCrashSight.so] 0x0000000000000001 (NEEDED)             Shared library: [libc++_shared.so] 0x000000000000000e (SONAME)             Library soname: [libUE4.so]
  0x000000000000001e (FLAGS)              SYMBOLIC BIND_NOW
  0x000000006ffffffb (FLAGS_1)            NOW
  0x0000000000000007 (RELA)               0x3a7500
  0x0000000000000008 (RELASZ)             29283912 (bytes)
  0x0000000000000009 (RELAENT)            24 (bytes)
  0x000000006ffffff9 (RELACOUNT)          1210342
  0x0000000000000017 (JMPREL)             0x1f94b48
  0x0000000000000002 (PLTRELSZ)           19704 (bytes)
  0x0000000000000003 (PLTGOT)             0xb221058
  0x0000000000000014 (PLTREL)             RELA
  0x0000000000000006 (SYMTAB)             0x330
  0x000000000000000b (SYMENT)             24 (bytes)
  0x0000000000000005 (STRTAB)             0x1721c4
  0x000000000000000a (STRSZ)              2315065 (bytes)
  0x000000006ffffef5 (GNU_HASH)           0xecdf0
  0x0000000000000004 (HASH)               0x1294e4
  0x0000000000000019 (INIT_ARRAY)         0xb20ef90
  0x000000000000001b (INIT_ARRAYSZ)       11208 (bytes)
  0x000000000000001a (FINI_ARRAY)         0xb20ef80
  0x000000000000001c (FINI_ARRAYSZ)       16 (bytes)
  0x000000006ffffff0 (VERSYM)             0xda9b8
  0x000000006ffffffe (VERNEED)            0xeccf0
  0x000000006fffffff (VERNEEDNUM)         8
  0x0000000000000000 (NULL)               0x0

 

llvm-readelf.exe -s -W libUE4.so  // 輸出libUE4.so的.symtab段(調試符號)中所有符號(不截斷)

llvm-readelf.exe --debug-dump=frames-interp libUE4.so  // 輸出libUE4.so的eh_frame段的信息

llvm-readelf.exe -V libUE4.so // 輸出libUE4.so的符號版本信息

llvm-readelf.exe -x.data libc++_shared.so  // 以16進制的方式輸出libc++_shared.so的.data段內容到文本文件  注:libc++_shared.so來自於strip后的<android-ndk>\sources\cxx-stl\llvm-libc++\libs\arm64-v8a\libc++_shared.so

llvm-readelf.exe -x.note.gnu.build-id libUE4.so  // 以16進制的方式輸出libUE4.so的.note.gnu.build-id段內容  注:里面存儲着libUE4.so的BuildId,符號表匹配依賴這個     (BuildId: 72e1338dd3e2096ddc9555842ca24ecfafd2586e)

Hex dump of section '.note.gnu.build-id':
  0x00000308 04000000 14000000 03000000 474e5500 ............GNU.
  0x00000318 72e1338d d3e2096d dc955584 2ca24ecf r.3....m..U.,.N.
  0x00000328 afd2586e                            ..Xn

 

llvm-readelf.exe -p.shstrtab libtestSo.so   // 以字符串(char)的方式輸出libtestSo.so的.shstrtab段內容   注:utf16寬字符串會在解析時截斷

llvm-readelf.exe -c libssl.a  // 輸出靜態庫libssl.a中包括各個中間目標文件(*.o)中的符號信息

llvm-readelf.exe -n libUE4.so  // 輸出libUE4.so中所有note段的信息

 

llvm-readelf.exe -v  //  輸出readelf的版本信息

llvm-readelf.exe --help  //  輸出readelf的幫助信息

 

objdump

llvm-objdump.exe所在目錄在:<android-ndk>\toolchains\llvm\prebuilt\windows-x86_64\bin 

llvm-objdump.exe -v  //  輸出objdump的版本信息

llvm-objdump.exe --help  //  輸出objdump的幫助信息

llvm-objdump.exe -i  //  輸出支持的ELF的格式和架構(architecture)

 

llvm-objdump.exe -f libUE4.so  //  輸出libUE4.so的簡要信息

llvm-objdump.exe -h libUE4.so  //  輸出libUE4.so段表的信息   注:不輸出一些輔助性的段(如:符號表、字符串表、段名字符串表、重定位表等)

llvm-objdump.exe -x libUE4.so  // 輸出llibUE4.so整個頭的信息   注:包括段表的信息

llvm-objdump.exe -p libUE4.so  // 輸出llibUE4.so的program headers和dynsym段基本信息

llvm-objdump.exe -d -s libUE4.so  // 對libUE4.so中的代碼段進行反編譯,並以16進制的形式輸出

 

llvm-objdump.exe -a libpython2.7.a  // 列出.a靜態庫中所有的目標中間文件(*.o)

llvm-objdump.exe -t libUE4.so   // 顯示libUE4.so中的調試符號表

llvm-objdump.exe -T libtestSo.so   // 輸出libtestSo.so的動態鏈接符號表(dynsym段)

llvm-objdump.exe -T -C libtestSo.so  // 輸出libtestSo.so的動態鏈接符號表(dynsym段),並自動對c++符號名進行反修飾(Demangle)

llvm-objdump.exe -R libtestSo.so  // 輸出libtestSo.so的動態鏈接重定位信息(.rela.dyn段和.rela.plt段)

llvm-objdump.exe -R -C libtestSo.so  // 輸出libtestSo.so的動態鏈接重定位信息,並自動對c++符號名進行反修飾(Demangle)

llvm-objdump.exe -d libtestSo.so   // 對libtestSo.so中的包含機器指令的段進行反匯編  

llvm-objdump.exe -S libtestSo.so   // 顯示libtestSo.so源代碼和機器指令的段的反匯編代碼(包含-d參數功能)

llvm-objdump.exe -D libtestSo.so   // 對libtestSo.so所有的段進行反匯編

llvm-objdump.exe -r testSo.o  // 顯示中間文件testSo.o中重定位信息

llvm-objdump.exe -s libtestSo.so   // 以16進制的方式輸出libtestSo.so的內容

 

// 輸出libUE4.debug.so地址范圍為[0x0000000008277724, 0x0000000008277850]的機器指令進行反匯編,並自動其中c++符號名進行反修飾(Demangle)

llvm-objdump.exe -d -C libUE4.debug.so --start-address=0x0000000008277724 --stop-address=0x0000000008277850

注1:[0x0000000008277724, 0x0000000008277850]的機器指令對應UAkGameplayStatics::SetState(UAkStateValue const*, FName, FName)函數

注2:可通過命令:llvm-nm.exe -n -C libUE4.debug.so | findstr "UAkGameplayStatics::SetState"來獲取該函數的起始地址

 

// 輸出libUE4.debug.so地址范圍為[0x0000000008277724, 0x0000000008277850]的機器指令進行反匯編(配合源代碼),並自動其中c++符號名進行反修飾(Demangle)

llvm-objdump.exe -S -C libUE4.debug.so --start-address=0x0000000008277724 --stop-address=0x0000000008277850 --include="D:\svn\MyGame\Plugins\Wwise\Source\AkAudio\Private"

注:可通過命令:llvm-addr2line.exe -e libUE4.debug.so 0000000008277724來獲取地址為0000000008277724(該地址為RVA地址,即已減去libUE4.so模塊的基地址)對應的源代碼文件和行數,得到如下結果

      E:/tiyan/MyGame/Plugins/Wwise/Source/AkAudio/Private/AkGameplayStatics.cpp:377

 

參考

程序員的自我修養

Executable and Linkable Format (ELF) 

ELF(Special Sections) 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM