GNU二进制开发工具集-GNU Binutils
2018-05-07 15:45:51 阿炯

在Linux下开发的朋友们都不可避免地用到一些工具,包括:addr2line、ar、gprof、nm、objcopy、objdump、ranlib、size、strings、strip等等。其实这一系列的工具,就是所谓的 Binutils,当然 GNU 就表示它们都是可以自由地使用的 GNU 软件。这些工具有助于汇编、链接、反汇编和检查二进制可执行文件、目标文件、库和汇编代码。

GNU Binutils,是 GNU Binary Utilities 的简写,一般简称为 Binutils。中文可以翻译为 GNU 的二进制工具集,系一组二进制工具的集合。即 Binutils 不是指某一个工具,而是指一组工具,并且这些工具都是专门针对于二进制的。这些工具的目的是用于操作二进制文件的,而不是针对于文本或者源代码。在 Linux 环境下,这种二进制文件主要指 *.o 文件和 elf 执行文件。显然编译源代码的是 gcc,所以 Binutils 不包含 gcc(这是一种简单的说法,实际上还是有很多关联的)。

Binutils 工具

现在已经知道,Binutils 是一组工具集合,那到底包含了哪些工具呢?

其中比较重要的是 ld 和 as。

ld -- 链接器
将多个目标文件,链接成一个可执行文件(或目标库文件)。

as -- 汇编器
将汇编源代码,编译为(目标)机器代码。

另外还有下面这些相对次要的,但非常实用的工具:

addr2line
将地址转换为(源文件和)行号的工具,一般主要用于反汇编。

ar
用来操作(.a)档案文件,比如创建,修改,提取内容等。archive是一个包含多个被包含文件的单一文件(也称之为库文件),其结构保证了可以从中检索并得到原始的被包含文件(称之为archive中的member)。member的原始文件内容、模式(权限)、时间戳、所有着和组等属性都被保存在 archive中。member被提取后,他们的属性被恢复到初始状态。ar主要用于创建C库文件,即创建和管理静态库。

c++filt
解码 C++ 的符号

dlltool
创建Windows 动态库

gold
一个新的,速度更快的,只针对于ELF的链接器(可能还不是很成熟稳定)。

gprof
gprof被用来测量程序的性能。它记录每个函数被调用的次数以及相应的执行时间,这样就能锁定程序执行时花费时间最多的部分,对程序的优化就可集中于对它们的优化。

nlmconv
可以转换成NetWare Loadable Module目标文件格式

nm
列出目标文件中的符号。nm用来列出目标文件中的符号,可以帮助程序员定位和分析执行程序和目标文件中的符号信息和它的属性。如果没有目标文件作为参数传递给nm,nm假定目标文件为a.out。

objcopy
拷贝并翻译(转换)文件,可用于不同格式的二进制文件的转换。objcopy可以将一种格式的目标文件转化为另外一种格式的目标文件,它使用GNU BFD库进行读/写目标文件。使用BFD,objcopy就能将原格式的目标文件转化为不同格式的目标文件。

objdump
显示目标(二进制)文件中的信息。objdump用来显示目标文件的信息,可以通过选项控制显示那些特定信息,objdump一个最大的用处恐怕就是将C代码反汇编了,在嵌入式软件开发过程中也可以用它查看执行文件或库文件的信息。

ranlib
产生静态库的索引

readelf
显示 ELF(可执行和可链接格式) 格式的(目标)文件的信息。 readelf用来显示ELF格式目标文件的信息,可通过参数选项来控制显示哪些特定信息(注意: readelf不支持显示archive文档,也不支持64位的ELF文件)。

注意: readelf只能用于ELF格式目标文件,且选项中至少要指定一个(除V, H外)的选项。

size
显示目标文件或(.a)档案文件中的节(section)的大小。

strings
显示(二进制)文件中的(可打印)的字符串信息。

strip
从二进制文件中删除调试符号。一般用来把可执行文件中的一些信息(比如 debug 信息)去除掉,以实现在不影响程序功能的前提下,减少可执行文件的大小,减少程序的空间占用。

windmc
产生Windows消息资源

windres
Windows 资源档编译器

示例用法

objdump 检查二进制文件
objdump -d /bin/ls  # 反汇编 ls 命令
objdump -x /bin/ls  # 显示完整的二进制信息

nm 显示目标文件中的符号
nm /bin/ls  # 列出 ls 二进制文件中的符号

strings 提取可读文本
strings /bin/ls  # 从二进制文件中提取可读文本

readelf 检查 ELF 文件
readelf -h /bin/ls  # 显示 ELF 标头

strip 删除调试符号
strip myprogram  # 通过删除符号来减少二进制大小

创建并链接汇编程序
    编写一个汇编程序(hello.s)

.global _start
.section .text
_start:
    mov $1, %rax
    mov $1, %rdi
    mov $msg, %rsi
    mov $len, %rdx
    syscall

    mov $60, %rax
    xor %rdi, %rdi
    syscall

.section .data
msg: .ascii "Hello, Binutils!\n"
len = . - msg

用 as 组装
as hello.s -o hello.o

使用 ld 来链接
ld hello.o -o hello

运行程序
./hello

输出
Hello, Binutils!


最新版本:2.4
GNU Binutils v2.44 已于2025年2月上旬发布。值得一提的是,公告内容指出:与以往不同的是,本次发布的 binutils-2.44.tar 包不包含 gold linker 的源代码。因为 GNU Gold linker 已被弃用,除非有志愿者愿意继续开发和维护,否则最终将被移除。相关源代码可在 binutils-with-gold-2.44.tar tar 包中找到。往后奇数版本的 binutils(2.45、2.47 等)将只包含 binutils.2.xx.tar 包,而偶数版本将同时包含 binutils-2.xx.tar 和 binutils-with-gold-2.xx.tar 包,直到其被完全删除。

GNU Gold 由谷歌于二十多年前推出,旨在提高链接性能,使其比 GNU 链接器更快。事实证明,GNU Gold 确实达到了预期目的,并证明了更快地链接 ELF 对象是可能的。但随着谷歌更依赖于性能更优的 LLVM 工具链,GNU Gold 缺乏投资且开发活动逐渐停滞。科技网站 Phoronix 指出随着越来越多的企业组织转而使用 LLVM 工具链,以及那些希望获得更快 ELF 链接性能的人可能会转而使用 Mold 链接器,而不是投入资源来发展 GNU Gold。除非出现奇迹,否则 GNU Gold linker 将来可能会被彻底放弃。

GNU 项目于2025年8月发布了 Binutils v2.45,这是 GNU 工具链的重要更新之一。虽然它不像 GCC 或 GDB 那样经常出现在开发者视野中,但 Binutils 在系统底层构建中扮演着不可或缺的角色。简言之,GNU Binutils 是一套用于创建、检查和管理目标文件与可执行程序的命令行工具集合,包括著名的 as(汇编器)、ld(链接器)以及 objdump、readelf 等实用工具。与 GCC(编译器)、Glibc(C 标准库)以及 GDB(调试器)并称为 GNU 开发工具链的“四大金刚”,是嵌入式开发、系统编程、底层调试中不可缺少的一部分。v2.45 带来的亮点如下:
更强的堆栈回溯支持
在此版本中,GNU 汇编器(GAS)默认会生成带有 SHT_GNU_SFRAME 类型标记的段,并在段头加入新的标志位 SFRAME_F_FDE_FUNC_START_PCREL。这听起来有些“术语密集”,但简单说就是:为调试和异进程堆栈分析工具提供了更完整、更可靠的栈帧信息,使得调试过程更精确,尤其对调试崩溃报告、性能分析等有很大帮助。特别值得一提的是,s390x 架构(常用于大型主机)也终于支持标准的 CFI(调用帧信息)生成 SFrame,开发者可以获得更完善的回溯信息。

架构支持大幅增强
Binutils 一直以来都在积极拥抱新架构和新特性,这次也不例外。

RISC-V 方面
支持最新的 RISC-V 特权规范 v1.13;
引入了三个新配置文件(Profile 20、22、23),便于细分设备支持;
新增 .bfloat16 指令支持,适用于低精度机器学习浮点计算;
识别更多 标准扩展与厂商自定义扩展,更好支持定制化芯片。
对于芯片设计者、嵌入式开发者来说,这是一大助力。

Arm 平台增强
新增 -march=armv9.6-a 架构标志,带来多项扩展支持,包括:
+sme2p2:矩阵扩展增强;+ssve-aes:矢量加密支持;+f8f32mm:混合精度浮点矩阵乘法。

这使得 SoC 厂商可以提前在工具链中测试 2025 年及以后芯片的功能,开发效率更高。

x86 与 LoongArch 也有动作
x86 架构
支持来自国产兆芯 Zhaoxin 的 PadLock XMODX 加密指令,增强加密硬件加速兼容性;
移除了对 AVX10.2 的 256 位 rounding 路径支持(该功能已被弃用,清理了冗余代码路径);

LoongArch 架构
为 LA32R 指令集增加了别名支持,简化汇编编写;
在表达式边界、对齐处理等方面提供更明确的编译警告;
这些细节优化将改善国产 LoongArch 平台在开源工具链中的可用性与易用性。

新增 GAS 汇编器诊断指令
GAS(GNU 汇编器)引入了两个新的预处理控制指令:
.errif:如果条件成立,在文件末尾报错;
.warnif:如果条件成立,在文件末尾发出警告;

它们特别适合用在固件开发、嵌入式系统或低层代码中,让开发者根据特定条件控制编译行为,但又不干扰正常流程。以更灵活的诊断手段,帮助发现潜在错误,又不影响构建流程的稳定性。虽然 Binutils 的每次更新不像新桌面环境或内核那样令人兴奋,但它的作用就像系统大厦中的地基——每一项增强都能让开发更高效,系统更稳定。v2.45 带来了:更可靠的堆栈回溯信息;对 RISC-V、Arm、x86、LoongArch 等架构的广泛更新;面向 AI 浮点优化的新指令支持;更人性化的汇编诊断工具。


官方主页:http://www.gnu.org/software/binutils/
参考页面:
GNU Binutils
GNU Binutils 详解