linux nm/objdump/readelf/addr2line命令详解
我们在开发过程中通过需要反汇编查看问题,那么我们这里使用rk3568开发板来举例nm/objdump/readelf/addr2line 分析动态库和可执行文件以及.o文件。
1,我们举例nm/objdump/readelf/addr2line解析linux 内核文件vmlinux
(1),addr2line解析地址0xffffffc00911a2e
lark@ubuntu:~/Public/rk356x-linux/kernel$ addr2line -e vmlinux -f -C ffffffc00911a2e4
skb_copy_bits
/home/lark/Public/rk356x-linux/kernel/net/core/skbuff.c:3610
使用上面的addr2line的时候记得编译时需要在Makefile里面加入-g,并且在编译net模块里面的编译里面不要使用strip,而要使用not strip的版本。
(2),readelf 查看skb_copy_bits
lark@ubuntu:~/Public/rk356x-linux/kernel$ readelf -s vmlinux | grep "skb_copy_bits"
149816: ffffffc009b5c4da 0 NOTYPE LOCAL DEFAULT 8 __kstrtab_skb_copy_bits
149817: ffffffc009b55ba3 0 NOTYPE LOCAL DEFAULT 8 __kstrtabns_skb_copy_bits
149819: ffffffc009b0a864 0 NOTYPE LOCAL DEFAULT 6 __ksymtab_skb_copy_bits
196394: ffffffc00911a2e4 548 FUNC GLOBAL DEFAULT 2 skb_copy_bits
(3),objdump查看skb_copy_bits
lark@ubuntu:~/Public/rk356x-linux$ objdump -d kernel/vmlinux | grep "skb_copy_bits"
ffffffc008bca2e8: 94153fff bl ffffffc00911a2e4 <skb_copy_bits>
ffffffc008bd0c50: 941525a5 bl ffffffc00911a2e4 <skb_copy_bits>
ffffffc008bd0e48: 94152527 bl ffffffc00911a2e4 <skb_copy_bits>
ffffffc008bd1498: 94152393 bl ffffffc00911a2e4 <skb_copy_bits>
ffffffc008bd154c: 94152366 bl ffffffc00911a2e4 <skb_copy_bits>
ffffffc008bd8730: 941506ed bl ffffffc00911a2e4 <skb_copy_bits>
ffffffc008bd8838: 941506ab bl ffffffc00911a2e4 <skb_copy_bits>
ffffffc008c5e7b8: 9412eecb bl ffffffc00911a2e4 <skb_copy_bits>
ffffffc008c6de38: 9412b12b bl ffffffc00911a2e4 <skb_copy_bits>
ffffffc008c6e234: 9412b02c bl ffffffc00911a2e4 <skb_copy_bits>
ffffffc008c6e530: 9412af6d bl ffffffc00911a2e4 <skb_copy_bits>
ffffffc00911a2e4 <skb_copy_bits>:
ffffffc00911a318: 54000d0b b.lt ffffffc00911a4b8 <skb_copy_bits+0x1d4> // b.tstop
ffffffc00911a330: 54000d4c b.gt ffffffc00911a4d8 <skb_copy_bits+0x1f4>
ffffffc00911a344: 340007e1 cbz w1, ffffffc00911a440 <skb_copy_bits+0x15c>
ffffffc00911a360: 14000008 b ffffffc00911a380 <skb_copy_bits+0x9c>
ffffffc00911a37c: 5400060d b.le ffffffc00911a43c <skb_copy_bits+0x158>
ffffffc00911a388: 5400056b b.lt ffffffc00911a434 <skb_copy_bits+0x150> // b.tstop
ffffffc00911a3a4: 54fffe0d b.le ffffffc00911a364 <skb_copy_bits+0x80>
ffffffc00911a3cc: 340001d3 cbz w19, ffffffc00911a404 <skb_copy_bits+0x120>
ffffffc00911a410: 54fffaa1 b.ne ffffffc00911a364 <skb_copy_bits+0x80> // b.any
ffffffc00911a438: 17ffffd5 b ffffffc00911a38c <skb_copy_bits+0xa8>
ffffffc00911a444: b5000096 cbnz x22, ffffffc00911a454 <skb_copy_bits+0x170>
ffffffc00911a448: 1400001a b ffffffc00911a4b0 <skb_copy_bits+0x1cc>
ffffffc00911a450: b4000316 cbz x22, ffffffc00911a4b0 <skb_copy_bits+0x1cc>
ffffffc00911a45c: 540003ab b.lt ffffffc00911a4d0 <skb_copy_bits+0x1ec> // b.tstop
ffffffc00911a480: 54fffe6d b.le ffffffc00911a44c <skb_copy_bits+0x168>
ffffffc00911a498: 97ffff93 bl ffffffc00911a2e4 <skb_copy_bits>
ffffffc00911a49c: 350000c0 cbnz w0, ffffffc00911a4b4 <skb_copy_bits+0x1d0>
ffffffc00911a4a4: 54fffba0 b.eq ffffffc00911a418 <skb_copy_bits+0x134> // b.none
ffffffc00911a4ac: b5fffd56 cbnz x22, ffffffc00911a454 <skb_copy_bits+0x170>
ffffffc00911a4b0: 34fffb55 cbz w21, ffffffc00911a418 <skb_copy_bits+0x134>
ffffffc00911a4d4: 17ffffe3 b ffffffc00911a460 <skb_copy_bits+0x17c>
ffffffc00911a4f8: 54fff900 b.eq ffffffc00911a418 <skb_copy_bits+0x134> // b.none
ffffffc00911a504: 17ffff8c b ffffffc00911a334 <skb_copy_bits+0x50>
ffffffc00911c8a0: 97fff691 bl ffffffc00911a2e4 <skb_copy_bits>
(4),nm/nm -gDC查看skb_copy_bits
lark@ubuntu:~/Public/rk356x-linux/kernel$ nm vmlinux | grep "skb_copy_bits"
ffffffc009b55ba3 r __kstrtabns_skb_copy_bits
ffffffc009b5c4da r __kstrtab_skb_copy_bits
ffffffc009b0a864 r __ksymtab_skb_copy_bits
ffffffc00911a2e4 T skb_copy_bits
2,nm/objdump/readelf/addr2line参数说明
(1)objdump参数说明:
-d/--disassemble:反汇编可执行段(.text等)
-S/--source:混合显示源码和汇编(需编译时加-g)
-s/--full-contents:显示所有段原始内容(十六进制+ASCII)
符号分析参数
-t/--syms:显示符号表(含全局变量/函数地址)
-T/--dynamic-syms:显示动态符号表(用于共享库)
段信息参数
-h/--section-headers:显示段头表(各段偏移/大小)
-x/--all-headers:显示所有头信息(ELF头+段头+符号表)
架构参数
-m/--architecture=<arch>:指定目标架构(如-m i386:x86-64)
(2)nm参数说明:
-A 显示文件名(适用于多文件) nm -A *.o
-C 解码 C++ 符号(demangle) nm -C lib.so
-D 显示动态符号(共享库特有) nm -D libc.so.6
-g 仅显示外部(全局)符号 nm -g a.out
-l 显示源代码行号(需编译时加 -g) nm -l program
-S 显示符号大小 nm -S kernel.o
-u 仅显示未定义符号 nm -u failed.o
--defined-only 仅显示已定义符号 nm --defined-only lib.a
--no-demangle 禁止 C++ 符号解码 nm --no-demangle
-t <format> 自定义输出格式(dox 十进制/八进制/十六进制) nm -t x lib.o
(3)readelf参数说明:
-h:显示ELF文件头(魔数、架构、入口地址等)readelf -h libtest.so # 查看动态库文件头
-l:列出程序头(Program Headers),描述内存布局readelf -l a.out # 分析可执行文件内存段节区分析
-S:显示所有节区头(Section Headers),包括.text/.data等readelf -S test.o # 查看目标文件节
-x <section>:以十六进制导出指定节区内容readelf -x .text program # 导出代码段机器码符号与重定位
-s:显示符号表(函数/变量名、地址、绑定类型)readelf -s libc.so.6 # 查看glibc导出符号
-r:查看重定位表(动态链接依赖项)readelf -r demo # 分析可执行文件重定位项动态链接信息
-d:显示动态节(Dynamic Section),如依赖库NEEDED89readelf -d nginx # 查看二进制依赖的so文件
(4)addr2line的使用说明:
参数 | 作用 | 适用场景 |
---|---|---|
-e <file> | 指定目标可执行文件或共享库(默认a.out ) | 解析非默认名称的二进制文件 |
-f | 显示函数名称 | 定位崩溃函数上下文 |
-C | 解混淆C++符号(还原可读函数名) | 分析C++程序崩溃点 |
-s | 仅显示文件名(隐藏路径) | 简化输出信息 |
-p | 美化输出格式(地址/函数/位置单行显示) | 增强可读性 |
-i | 显示内联函数调用链 | 分析优化后的代码逻辑 |
-a | 显示原始地址(十六进制) | 地址校验 |
-j <section> | 指定段名称(如.text )替代绝对地址 | 分析内核模块 |
3,nm/objdump/readelf/addr2line解析linux 动态库
lark@ubuntu:~/Public/rk356x-linux/debian/overlay-debug/usr/lib$ nm -D libpng12.so | grep "png_set_bgr"
000000000000ad64 T png_set_bgr
lark@ubuntu:~/Public/rk356x-linux/debian/overlay-debug/usr/lib$ ./../../../../prebuilts/gcc/linux-x86/aarch64/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu-objdump -d libpng12.so | grep "png_set_bgr"
00000000000046f0 <png_set_bgr@plt>:
000000000000ad64 <png_set_bgr@@PNG12_0>:
ad64: b4000080 cbz x0, ad74 <png_set_bgr@@PNG12_0+0x10>
f4e0: 97ffd484 bl 46f0 <png_set_bgr@plt>
10c08: 97ffceba bl 46f0 <png_set_bgr@plt>
lark@ubuntu:~/Public/rk356x-linux/debian/overlay-debug/usr/lib$ ./../../../../prebuilts/gcc/linux-x86/aarch64/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu-readelf -s libpng12.so | grep "png_set_bgr"
230: 000000000000ad64 20 FUNC GLOBAL DEFAULT 11 png_set_bgr@@PNG12_0
4,aarch64-none-linux-gnu-nm/objdump/readelf/addr2line解析.o文件
(0),查看编译服务器
lark@ubuntu:~/Public/rk356x-linux/kernel$ strings vmlinux | grep "gcc"
Linux version 5.10.160 (lark@ubuntu) (aarch64-none-linux-gnu-gcc (GNU Toolchain for the A-profile Architecture 10.3-2021.07 (arm-10.29)) 10.3.1 20210621, GNU ld (GNU Toolchain for the A-profile Architecture 10.3-2021.07 (arm-10.29)) 2.36.1.20210621) #1 SMP Fri May 9 07:51:32 PDT 2025
(1),aarch64-none-linux-gnu-nm 查看skb_copy_bits
lark@ubuntu:~/Public/rk356x-linux$ ./prebuilts/gcc/linux-x86/aarch64/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu-nm kernel/vmlinux.o | grep "skb_copy_bits"
ffffffc009b55ba3 r __kstrtabns_skb_copy_bits
ffffffc009b5c4da r __kstrtab_skb_copy_bits
ffffffc009b0a864 r __ksymtab_skb_copy_bits
ffffffc00911a2e4 T skb_copy_bits
(2),aarch64-none-linux-gnu-objdump 查看skb_copy_bits
lark@ubuntu:~/Public/rk356x-linux$ ./prebuilts/gcc/linux-x86/aarch64/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu-objdump -d kernel/vmlinux.o | grep "skb_copy_bits"
64ab1c: 94000000 bl 1102764 <skb_copy_bits>
64abec: 94000000 bl 1102764 <skb_copy_bits>
64ac50: 94000000 bl 1102764 <skb_copy_bits>
bb3768: 94000000 bl 1102764 <skb_copy_bits>
bba0d0: 94000000 bl 1102764 <skb_copy_bits>
bba2c8: 94000000 bl 1102764 <skb_copy_bits>
c579b0: 94000000 bl 1102764 <skb_copy_bits>
0000000001102764 <skb_copy_bits>:1102798: 54000d0b b.lt 1102938 <skb_copy_bits+0x1d4> // b.tstop
11027b0: 54000d4c b.gt 1102958 <skb_copy_bits+0x1f4>
11027c4: 340007e1 cbz w1, 11028c0 <skb_copy_bits+0x15c>
11027e0: 14000008 b 1102800 <skb_copy_bits+0x9c>
11027fc: 5400060d b.le 11028bc <skb_copy_bits+0x158>
1102808: 5400056b b.lt 11028b4 <skb_copy_bits+0x150> // b.tstop
1102824: 54fffe0d b.le 11027e4 <skb_copy_bits+0x80>
110284c: 340001d3 cbz w19, 1102884 <skb_copy_bits+0x120>
1102890: 54fffaa1 b.ne 11027e4 <skb_copy_bits+0x80> // b.any
(3),aarch64-none-linux-gnu-readelf 查看skb_copy_bits
lark@ubuntu:~/Public/rk356x-linux$ ./prebuilts/gcc/linux-x86/aarch64/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu-readelf -s kernel/vmlinux.o | grep "skb_copy_bits"
244692: 0000000001102764 548 FUNC GLOBAL DEFAULT 2 skb_copy_bits
(4),aarch64-none-linux-gnu-addr2line解析地址0xffffffc00911a2e
lark@ubuntu:~/Public/rk356x-linux$ ./prebuilts/gcc/linux-x86/aarch64/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu-addr2line -e kernel/vmlinux.o -f -C ffffffc00911a2e4
skb_copy_bits
/home/lark/Public/rk356x-linux/kernel/net/core/skbuff.c:3610