当前位置: 首页 > 工具软件 > GNU Binutils > 使用案例 >

GNU binutils工具集

雍飞雨
2023-12-01

前言

GNU binutils工具提供了一系列二进制工具,用于日常开发过程中对程序调试和维护,经常会用到的工具如下:

  • as:汇编编译器,用于将汇编代码编译成目标文件;
  • addr2line:用于得到程序指令地址所对应的函数,以及函数所在的源文件名和行号信息;
  • ar:用于创建和修改档案文件,以及从档案文件中抽取文件,典型的档案文件如静态库(.a文件);
  • ld:链接器,用于目标文件或库的链接;
  • nm:用于列出程序文件中的符号信息;
  • objcopy:可用于从程序文件中拷贝指定段;
  • objdump:能显示程序文件的相关信息,同时可支持对程序文件进行反汇编;
  • ranlib:用于生成一个档案文件的内容索引,以加快对档案文件的查找速度;
  • size:用于查询程序文件中各个段的大小;
  • strings:用于查看程序文件内的可显示字符串;
  • strip:用于剥去程序文件的调试信息,以减少程序文件所占用的存储空间;
  • readelf:用于查询ELF格式程序文件的段、节等信息.

下文会简单描述上述部分工具的基本用法,更为详细的使用方法建议查看对应工具的man和info信息。

addr2line

addr2line可根据程序指令地址查找到所对应的函数名、以及函数所在的源文件名和行号。当含有调试信息的执行程序出现crash时,可使用addr2line快速定位出错代码的位置。其基本使用格式如下:

addr2line <程序运行地址> -e <可执行文件路径>

nm

nm工具用于列出程序文件中的符号信息。以一个简单的hello world程序为例:

shell # nm helloworld
0000000100002008 d __dyld_private
0000000100000000 T __mh_execute_header
0000000100000f60 T _main
                 U _printf
                 U dyld_stub_binder

nm所列出的每一行信息由三部分组成:

  • 第一列表示程序运行时符号在内存中的地址。对于程序中未定义的符号,因为不清楚运行地址,因此显示为空;
  • 第二列表示相应的符号所在的段,每个字符有着特定的含义;
  • 第三列则是符号的名称。

对于第二列中的字符含义如下表所示:

字符含义
A表示符号所对应的值是绝对的,并且在后续的链接过程中也不会改变
B或b表示符号位于未初始化的数据段(.bss段)中,该段用于包含初始化为0或未初始化的数据
C表示未被初始化的公共符号
D或d表示符号位于初始化的数据段(.data段)中
N表示符号是调试用的
R或r表示符号位于只读数据段(.rdata)中
T或t表示符号位于代码段(.text段)中
U表示符号未被定义

nm常用选项

通常程序中包含的符号种类比脚繁杂,可以定制选项显示需要查看的符号信息,一些常用的选项如下:

  • -g或–extern-only:仅显示全局符号;
  • -u或–undefined-only:仅显示未定义的符号;
  • –defined-only:仅显示已定义的符号;
  • -l或–line-numbers:借助调试信息查找每个符号所在文件名及对应行号。

objcopy

objcopy可以实现拷贝目标文件中特定的段,并且支持格式转化。objcopy支持的选项很多,比较常见的用法是创建二进制bin文件活着剥离目标文件中的调试信息。

使用objcopy生成纯二进制文件

在嵌入式开发中,经常需要向开发板rom中烧录引导程序,此时就可以使用objcopy从编译好的目标文件中将二进制执行代码拷贝出来。

objcopy -O binary boot.elf boot.bin

使用objcopy生成单独的调试信息文件

一般在程序发布时,是不会携带调试信息的,但是可以将调试信息提取出来作为文件,在程序调试时,可以将调试文件单独进行加载,比如gdb已经支持这个功能。

objcopy --only-keep-debug a.out a.out.dbg

objdump

objdump工具可用于查看目标文件或者可执行文件的段、节等构成信息,也可以用来对目标文件进行反汇编。objdump的常用选项如下:

  • -f:显示程序文件的头信息;
  • -h:显示程序中的段信息;
  • -s:显示某一个段的具体信息
  • -d:对程序进行反汇编后,显示程序文件的汇编代码;
  • -S:通常与-d选项搭配,用于指示objdump在反汇编时同时显示汇编代码所对应的C/C++源程序;

使用反汇编

使用objdump对程序文件进行反汇编,是日常调测用的较多的一个功能:

objdump -d -S a.out > a.out.S

strings

strings用于查看程序文件中的可显示字符,功能相对简单。在此查看一个最简单的helloworld程序中包含的字符串:

shell # strings helloworld
/lib64/ld-linux-x86-64.so.2
libc.so.6
printf
__cxa_finalize
__libc_start_main
__stack_chk_fail
GLIBC_2.2.5
GLIBC_2.4
_ITM_deregisterTMCloneTable
__gmon_start__
_ITM_registerTMCloneTable
u/UH
[]A\A]A^A_
hello world!
;*3$"

对于strings工具来说,更为常见的用法时为了查询系统中运行模块的版本信息,相对于查看模块运行日志,strings提供了一个更快捷的手段,当然这需要开发过程中在程序中增加特定版本信息的字符串。

相关参考

  • 《专业嵌入式软件开发:全面走向高质高效编程》
  • 《Linux Man Pages》
 类似资料: