TinyOS07:elf文件格式及分析工具objdump

objdump是GUN中专门用于将二进制目标代码从一种格式转换成另一种格式的二进制工具(对象文件格式分析工具),并且在转存过程需可以对二进制代码进行相关操作;

ELF简单来说就是一种跨平台的二进制文件。

GNU中的objdump

  1. objdump属于GNU中的二进制工具,GNU中的二进制工具专门用于将二进制目标代码从一种格式转换为另一种格式(dump单词本身有转存的意思)
  2. 与objdump类似的GNU二进制工具例如objcopy,用于从一个文件拷贝目标代码到另一个文件,并在这一过程中执行各种转换。
  3. objdump和objcopy的实现都是基于灵活的bfd二进制能够操纵函数库之上,基于这个库函数的工具能够很方便地操纵二进制目标文件。
  4. 例如通过objdump查看可执行文件的内容:使用命令如下
objdump -x -d -s 文件名
//-x:显示文件的所有头
//-d:反汇编任一可执行段落的内容
//-s:将程序的源代码与其对应的反汇编代码混合现实

例如通过objdump输出的示例程序头部分的内容:
这里写图片描述

ELF文件

  1. Linux中的ELF(Executable and Linkable Format,可执行连接格式)是UNIX系统实验室(USL)作为应用程序二进制接口(Application Binary Interface,ABI)而开发和发布的。扩展名为elf,可用作不同操作系统之间可移植的二进制文件格式,即是一种跨平台的二进制标准。
  2. 如果使用gcc命令的“-g”选项来编译源代码,那么objdump的输出还可以包含应用程序源代码的完整反汇编代码。如下例子显示了main函数的反汇编代码和对应的源代码:
    这里写图片描述

objdump的使用

  1. objdump -t 查看对象文件所有的符号列表,相当于 nm -s objfilename,如:
objdump -t libtest1.o的结果为:
SYMBOL TABLE:
00000000 l    df *ABS*  00000000 libtest1.c
00000000 l    d  .text  00000000 .text
00000000 l    d  .data  00000000 .data
00000000 l    d  .bss   00000000 .bss
00000000 l    d  .rodata        00000000 .rodata
00000000 l    d  .note.GNU-stack        00000000 .note.GNU-stack
00000000 l    d  .comment       00000000 .comment
00000000 g     F .text  00000014 print_test1
00000000         *UND*  00000000 puts
  1. 使用objdump查看源代码:
    http://blog.csdn.net/willand1981/article/details/5728972
    如何使用 objdump 查看源代码
    1、 在编译时必须使用-g选项,-g意为debug,一般可以修改源代码的 Makefile来实现 如:
    CC = (CROSSCOMPILE)gccCC= (CROSSCOM_PILE)gcc -g
    使成生的vmlinux中含有debug信息
    2、所有生成 .o 的 rule 中再加一条 /其他参数除了-c外抄生成.o文件用的参数/
    CC -E -dD -C <>/preprocessing/ <script type="math/tex" id="MathJax-Element-2">< > /preprocessing/</script>(shell pwd)/$<
    生成预处理文件从这个文件里面能很容易找到 c 源文件的宏定义
    3、objdump -h vmlinux > vmlinux.txt
    显示 linux 内核段信息,如段的开始虚拟地址,段的长度
    4、objdump -S -l -z vmlinux > vmlinux.txt
    反汇编 vmlinux 到vmlinux.txt, vmlinux.txt 含有汇编和 c 源文件的混合代码,看起来很方 便。而且能一步步看linux怎么一步步运行的。
    5、objdump -S -l -z -j xxxx(section name) vmlinux > vmlinux.txt 反汇编 linux 内核段 xxxx 到文件 vmlinux.txt 中。
    6、objdump -x vmlinux > x.txt
    vmliux中所有段的头信息,其中包口vmlinux的入口地址等
    7、objdump –debugging vmlinux > debugging.txt
    很多有用的debug信息,如函数名,结构体定义等
    我觉的用根据以上信息,ultraedit看很方便。尤其在vmlinux.txt中选中文件名,
    用ultraedit右键的open能马上打开文件,很方便。
  2. –line-numbers -l 用文件名和行号标注相应的目标代码,仅仅和-d、-D或者-r一起使用 使用-ld和使用-d的区别不是很大,在源码级调试的时候有用,要求编译时使用了-g之类的调试编译选项。
    –source -S 尽可能反汇编出源代码,尤其当编译的时候指定了-g这种调试参数时,效果比较明显。隐含了-d参数。
  3. objdump常用的反汇编方法(老师分享的):
    1、objdump -j .text -Sl objtest | more
    ①、-S 尽可能反汇编出源代码,尤其当编译的时候指定了-g这种调试参数时,效果比较明显。隐含了-d参数。
    ②、-l 用文件名和行号标注相应的目标代码,仅仅和-d、-D或者-r一起使用,使用-ld和使用-d的区别不是很大,在源码级调试的时候有用,要求编译时使用了-g之类的调试编译选项
    ③、-j name 仅仅显示指定section的信息
    2、同时发现objdump这个指令功能强大,下面是几个我认为常用的option:
    ①、objdump -x obj 以某种分类信息的形式把目标文档的数据组织(被分为几大块)输出
    ②、objdump -t obj 输出目标文档的符号表
    ③、objdump -h obj 输出目标文档的section概括
  4. 编译过程示例:
//将源文件blink.c编译成目标文件blink.c;
1、avr-gcc -g -Wall -mmcu=atmega16 -c -o blink.o blink.c
//将目标文件blink.c连接成blink.elf二进制文件(elf文件其实跟.exe文件类似).
2、avr-gcc -g -Wall -mmcu=atmega16 -Wl,-Map,blink.map -o blink.elf blink.o
//通过objdumo将blink.elf文件反编译成blink.lst文件(lst文件是一个可读的编译程序列表,他能够用于计算指令周期和调试)
3、avr-objdump -h -S blink.elf > blink.lst
//objcopy将blink.lst文件解释成blink.hex十六进制文件
4、avr-objcopy -j .text -j .data -O ihex blink.elf blink.hex
5、avr-objcopy -j .eeprom --change-section-lma .eeprom=0 -O ihex blink.elf
link_eeprom.hex

ELF文件结构
http://blog.csdn.net/joker0910/article/details/7671769
这里写图片描述
静态变量、全局变量在ELF文件中的位置, 总结:
1.初始化了的全局变量和静态变量,最终被写入了.data字段。(.data字段存放的是已经初始化了的全局静态变量和局部静态变量)
2.未被初始化的静态变量,在汇编阶段完成后,被写入了.bss段。(.bss存放的是未初始化的全局变量和局部静态变量))
3.未被初始化的全局变量,直到执行链接,生成可执行文件后,才被写入.bss段。

objdump、GNU目标文件可执行文件常用命令

这里写图片描述

gcc:GCC编译器常用命令
这里写图片描述

ELF格式data、bss、text段内容调查连接:
http://www.docin.com/p-683111172.html

ELF格式文件符号表全解析及readelf命令使用方法:http://blog.csdn.net/edonlii/article/details/8779075

从交叉编译器生成的elf文件中读取全局变量信息
这个恐怕不是一个函数能解决的,ELF文件格式还是有点复杂的。 我以前做过类似的功能,从ELF文件中加载所有符号表信息,字符串信息,并下载代码。 我推荐你用一个开源的库:ELFIO。 我想这个库应该可以实现你的功能,只是你要去研究一下它的用法。 当然,你得首先对ELF文件格式有所了解。ELFIO库下载地址:

http://sourceforge.net/projects/elfio/

addr2line:把ELF文件的机器地址转换到代码对应的位置。

  1. add2line原来只要跟pc指针就行了。
    一般程序被dump后,dump信息里会有pc的指针内容,只要将这个pc指针地址作为add2line的地址,就能很快找出被dump的代码的位置。这个在嵌入式的程序的调试中很有用。
  2. 列表内容

用法:
add2line -e file [address…]
eg:add2line -e app.exe 0x00382316
上面app.exe为发生dump情况的程序,0x00382316为dump出来的pc指针地址,在pc上将这个命令执行一下就会得到出问题的代码的位置(文件名和行号)。

注意点:
编译的时候需加上-g选项,另外由于我们的c库文件是没有-g选项的,所以如果dump发生在c库函数里,那么这个方法就无能为力了。否则还是很好用的。

ELF文件分析相关工具(待完善)
-wwm-ChinaUnix博客:

http://www.01yun.com/cc/20130706/562869.html

ELF可执行文件分析工具集binutil, 包括以下工具:
ld - the GNU linker.
as - the GNU assembler.
addr2line - Converts addresses into filenames and line numbers.
ar - A utility for creating, modifying and extracting from archives.
c++filt - Filter to demangle encoded C++ symbols.
gprof - Displays profiling information.
nlmconv - Converts object code into an NLM.
nm - Lists symbols from object files.
objcopy - Copys and translates object files.
objdump - Displays information from object files.
ranlib - Generates an index to the contents of an archive.
readelf - Displays information from any ELF format object file.
size - Lists the section sizes of an object or archive file.
strings - Lists printable strings from files.
strip - Discards symbols.
windres - A compiler for Windows resource files.
其中部分工具对调试极有帮助,如:
你可以用objdump反汇编,查看目标文件或可执行文件内部信息。
你可以用addr2line把机器地址转换到代码对应的位置。
你可以用nm查看目标文件或可执行文件中的各种符号。
你可以用gprof分析各个函数的使用情况,找出性能的瓶颈所在(这需要加编译选项)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值