![如何使用 Linux 实用程序 objdump 反汇编多个函数?](https://linux22.com/image/176940/%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8%20Linux%20%E5%AE%9E%E7%94%A8%E7%A8%8B%E5%BA%8F%20objdump%20%E5%8F%8D%E6%B1%87%E7%BC%96%E5%A4%9A%E4%B8%AA%E5%87%BD%E6%95%B0%EF%BC%9F.png)
程序编译并生成二进制文件后,我们可以使用objdump
反汇编二进制文件并提取汇编代码和大量信息。
但是,使用-j .text
with objdump
,它会反汇编我不想要的整个函数(glibc、操作系统函数等...)。
我只想关注二进制文件中我自己的函数。使用nm
,可以仅查找用户定义的函数。提取这些函数的名称后,我只想反汇编这些函数。但是,我不想在objdump
生成它的拥抱转储文件中进行搜索并提取与我的函数相关的反汇编代码。
basicmath
假设我们有程序的二进制文件MiBench 基准测试。
使用nm
,可以仅查找该程序源代码中定义的函数。
下面的命令将显示我想要的功能(用户定义的功能)
nm -P tst.o | awk '$2 == "T" && $1 != "main" {print "b " $1}'
结果将是(考虑basicmath
程序)
b deg2rad
b rad2deg
b solveCubic
b usqrt
现在,我需要一种方法来告诉 objdump 仅反汇编这些函数并将结果写入单个文件。
答案1
我没有找到一种方法来告诉 binutils 或 elfutils 中的 objdump 程序将反汇编限制为特定函数。不过,有一些解决方法。
假设我们感兴趣的函数列表位于 file 中list
:
$ nm -P basicmath_small |
awk '{ if ($2 == "T" && $1 != "main" && substr($1,1,1) != "_") print $1}' > list
$ cat list
deg2rad
rad2deg
SolveCubic
usqrt
- 使用 awk 过滤来自 objdump 的大反汇编输出。每个感兴趣的区域都以一行开始,该行以
<functionname>:
空行(或文件结尾)结束并继续。
$ xargs < list | sed -e 's/^/<(/' -e 's/ /|/g' -e 's/$/)>:\$/' > rlist
$ cat rlist
<(deg2rad|rad2deg|SolveCubic|usqrt)>:$
$ objdump -d -j .text basicmath_small | awk -v rlist="$(cat rlist)" \
'{ if ($0 ~ rlist) doprint=1; if ($0 == "") doprint=0; if (doprint) print }'
0000000000400fc0 <rad2deg>:
400fc0: f2 0f 59 05 c8 4d 0a mulsd 0xa4dc8(%rip),%xmm0 # 4a5d90 <c2+0x10>
400fc7: 00
400fc8: f2 0f 5e 05 b8 4d 0a divsd 0xa4db8(%rip),%xmm0 # 4a5d88 <c2+0x8>
400fcf: 00
400fd0: c3 retq
400fd1: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1)
400fd6: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1)
400fdd: 00 00 00
0000000000400fe0 <deg2rad>:
400fe0: f2 0f 59 05 a0 4d 0a mulsd 0xa4da0(%rip),%xmm0 # 4a5d88 <c2+0x8>
400fe7: 00
400fe8: f2 0f 5e 05 a0 4d 0a divsd 0xa4da0(%rip),%xmm0 # 4a5d90 <c2+0x10>
400fef: 00
400ff0: c3 retq
400ff1: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1)
400ff8: 00 00 00
400ffb: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1)
0000000000401000 <SolveCubic>:
401000: f2 0f 5e c8 divsd %xmm0,%xmm1
...
- 使用Go 中的 objdump,这需要一个
-s regexp
选项
$ xargs < list | sed -e 's/^/^(/' -e 's/ /|/g' -e 's/$/)\$/' > rlist
$ cat rlist
^(deg2rad|rad2deg|SolveCubic|usqrt)$
$ go tool objdump -s "$(cat rlist)" basicmath_small
TEXT rad2deg(SB)
:0 0x400fc0 f20f5905c84d0a00 MULSD 0xa4dc8(IP), X0
:0 0x400fc8 f20f5e05b84d0a00 DIVSD 0xa4db8(IP), X0
:0 0x400fd0 c3 RET
TEXT deg2rad(SB)
:0 0x400fe0 f20f5905a04d0a00 MULSD 0xa4da0(IP), X0
:0 0x400fe8 f20f5e05a04d0a00 DIVSD 0xa4da0(IP), X0
:0 0x400ff0 c3 RET
TEXT SolveCubic(SB)
:0 0x401000 f20f5ec8 DIVSD X0, X1
...