gdbdisassemble/rs
也显示源字节和原始字节
使用这种格式,它实际上非常接近objdump -S
输出:
gdb -batch -ex "disassemble/rs $FUNCTION" "$EXECUTABLE"
main.c
#include <assert.h>
int myfunc(int i) {
i = i + 2;
i = i * 2;
return i;
}
int main(void) {
assert(myfunc(1) == 6);
assert(myfunc(2) == 8);
return 0;
}
编译和反汇编
gcc -O0 -ggdb3 -std=c99 -Wall -Wextra -pedantic -o main.out main.c
gdb -batch -ex "disassemble/rs myfunc" main.out
拆卸:
Dump of assembler code for function myfunc:
main.c:
3 int myfunc(int i) {
0x0000000000001135 <+0>: 55 push %rbp
0x0000000000001136 <+1>: 48 89 e5 mov %rsp,%rbp
0x0000000000001139 <+4>: 89 7d fc mov %edi,-0x4(%rbp)
4 i = i + 2;
0x000000000000113c <+7>: 83 45 fc 02 addl $0x2,-0x4(%rbp)
5 i = i * 2;
0x0000000000001140 <+11>: d1 65 fc shll -0x4(%rbp)
6 return i;
0x0000000000001143 <+14>: 8b 45 fc mov -0x4(%rbp),%eax
7 }
0x0000000000001146 <+17>: 5d pop %rbp
0x0000000000001147 <+18>: c3 retq
End of assembler dump.
已在Ubuntu 16.04,GDB 7.11.1上测试。
objdump + AWK解决方法
如以下所述打印段落:https : //unix.stackexchange.com/questions/82944/how-to-grep-for-text-in-a-file-and-display-the-paragraph-that-has-the -文本
objdump -d main.out | awk -v RS= '/^[[:xdigit:]]+ <FUNCTION>/'
例如:
objdump -d main.out | awk -v RS= '/^[[:xdigit:]]+ <myfunc>/'
给出:
0000000000001135 <myfunc>:
1135: 55 push %rbp
1136: 48 89 e5 mov %rsp,%rbp
1139: 89 7d fc mov %edi,-0x4(%rbp)
113c: 83 45 fc 02 addl $0x2,-0x4(%rbp)
1140: d1 65 fc shll -0x4(%rbp)
1143: 8b 45 fc mov -0x4(%rbp),%eax
1146: 5d pop %rbp
1147: c3 retq
使用时-S
,我不认为有一种防故障的方法,因为代码注释可以包含任何可能的序列...但是以下代码几乎一直有效:
objdump -S main.out | awk '/^[[:xdigit:]]+ <FUNCTION>:$/{flag=1;next}/^[[:xdigit:]]+ <.*>:$/{flag=0}flag'
改编自:如何在两个标记模式之间选择可能会用awk / sed多次出现的线条
邮件列表回复
邮件列表上有一个2010线程,它表明不可能:https : //sourceware.org/ml/binutils/2010-04/msg00445.html
除了gdb
Tom提出的解决方法外,他们还评论了另一种(更糟糕的)编译方法,-ffunction-section
即每部分放入一个函数然后转储该部分。
Nicolas Clifton给了它WONTFIX https://sourceware.org/ml/binutils/2015-07/msg00004.html,可能是因为GDB解决方法涵盖了该用例。
static
,编译器可能会将其内联到其调用位置。这可能意味着有可能实际上不是拆卸,任何功能本身。如果您可以发现其他功能的符号,但找不到所需的功能,则有力暗示该功能已内联。Valgrind仍可以引用原始的预内联函数,因为ELF文件调试信息存储了每个单独指令的来源,即使这些指令已移至其他位置。