disassemble/rs
소스 및 원시 바이트도 표시하는 gdb
이 형식을 사용하면 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 해결 방법
/unix/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 파일 디버깅 정보가 각 개별 명령이 시작된 위치를 저장하기 때문에 원래의 사전 인라인 함수를 계속 참조 할 수 있습니다.