一、readelf
readelf 命令用来显示一个或者多个 elf 格式的目标文件的信息,可以通过它的选项来控制显示哪些信息。
这个程序和objdump提供的功能类似,但是它显示的信息更为具体,并且它不依赖BFD库(BFD库是一个GNU项目,它的目标就是希望通过一种统一的接口来处理不同的目标文件),所以即使BFD库有什么bug存在的话也不会影响到readelf程序。
1.1 ELF文件类型
- 可重定位文件:用户和其他目标文件一起创建可执行文件或者共享目标文件,例如lib*.a文件。
- 可执行文件:用于生成进程映像,载入内存执行,例如编译好的可执行文件a.out。
- 共享目标文件:用于和其他共享目标文件或者可重定位文件一起生成elf目标文件或者和执行文件一起创建进程映像,例如lib*.so文件。
1.2 ELF文件作用
ELF文件参与程序的连接(建立一个程序)和程序的执行(运行一个程序),所以可以从不同的角度来看待elf格式的文件:
- 如果用于编译和链接(可重定位文件),则编译器和链接器将把 elf 文件看作是节头表描述的节的集合,程序头表可选。
- 如果用于加载执行(可执行文件),则加载器则将把elf文件看作是程序头表描述的段的集合,一个段可能包含多个节,节头表可选。
- 如果是共享文件,则两者都含有。
1.3 ELF文件总体组成
elf文件头描述elf文件的总体信息。包括:系统相关,类型相关,加载相关,链接相关。
- 系统相关表示:elf文件标识的魔术数,以及硬件和平台等相关信息,增加了elf文件的移植性,使交叉编译成为可能。
- 类型相关就是前面说的那个类型。
- 加载相关:包括程序头表相关信息。
- 链接相关:节头表相关信息。
1.4 选项
-a
--all
显示全部信息,等价于 -h -l -S -s -r -d -V -A -I.
-h
--file-header
显示elf文件开始的文件头信息.
-l
--program-headers
--segments
显示程序头(段头)信息(如果有的话)。
-S
--section-headers
--sections
显示节头信息(如果有的话)。
-g
--section-groups
显示节组信息(如果有的话)。
-t
--section-details
显示节的详细信息(-S的)。
-s
--syms
--symbols
显示符号表段中的项(如果有的话)。
-e
--headers
显示全部头信息,等价于: -h -l -S -n --notes 显示note段(内核注释)的信息。
-r
--relocs
显示可重定位段的信息。
-u
--unwind
显示unwind段信息。当前只支持IA64 ELF的unwind段信息。
-d
--dynamic
显示动态段的信息。
-V
--version-info
显示版本段的信息。
-A
--arch-specific
显示CPU构架信息。
-D
--use-dynamic
使用动态段中的符号表显示符号,而不是使用符号段。
-x <number or name>
--hex-dump=<number or name>
以16进制方式显示指定段内内容。number指定段表中段的索引,或字符串指定文件中的段名。
-w[liaprmfFsoR]
or
--debug-dump[=line,=info,=abbrev,=pubnames,=aranges,=macro,=frames,=frames-interp,=str,=loc,=Ranges]
显示调试段中指定的内容。
-I
--histogram
显示符号的时候,显示bucket list长度的柱状图。
-v
--version
显示readelf的版本信息。
-H
--help
显示readelf所支持的命令行选项。
-W
--wide
宽行输出。
二、objdump
objdump 命令是 Linux 下的反汇编目标文件或者可执行文件的命令, 是用查看目标文件或者可执行的目标文件的构成的 gcc工具。
-a
--archive-headers
# 显示档案库的成员信息,类似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@file 可以将选项集中到一个文件中,然后使用这个@file选项载入。
--endian={big|little}
# 指定目标文件的小端。这个项将影响反汇编出来的指令。在反汇编的文件没描述小端信息的时候用。例如S-records.
-f
--file-headers
显示objfile中每个文件的整体头部摘要信息。
-h@file 可以将选项集中到一个文件中,然后使用这个@file选项载入。
--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@file 可以将选项集中到一个文件中,然后使用这个@file选项载入。
显示文件的重定位入口。如果和-d或者-D一起使用,重定位部分以反汇编后的格式显示出来。
--dynamic-reloc
-R
显示文件的动态重定位入口,仅仅对于动态目标文件意义,比如某些共享库。
-s
--full-contents
显示指定section的完整内容。默认所有的非空section都会被显示。
-S
--source
尽可能反汇编出源代码,尤其当编译的时候指定了-g这种调试参数时,效果比较明显。隐含了-d参数。
--show-raw-insn
反汇编的时候,显示每条汇编指令对应的机器码,如不指定--prefix-addresses,这将是缺省选项。
--no-show-raw-insn
@file 可以将选项集中到一个文件中,然后使用这个@file选项载入。反汇编时,不显示汇编指令的机器码,如不指定--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
一般反汇编输出将省略大块的零,该选项使得这些零块也被反汇编。