gdb disassemble/rs
para mostrar os bytes originais e brutos também
Com este formato, fica muito próximo da objdump -S
saída:
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;
}
Compilar e desmontar
gcc -O0 -ggdb3 -std=c99 -Wall -Wextra -pedantic -o main.out main.c
gdb -batch -ex "disassemble/rs myfunc" main.out
Desmontagem:
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.
Testado em Ubuntu 16.04, GDB 7.11.1.
objdump + soluções alternativas do awk
Imprima o parágrafo conforme mencionado em: /unix/82944/how-to-grep-for-text-in-a-file-and-display-the-paragraph-that-has-the -texto
objdump -d main.out | awk -v RS= '/^[[:xdigit:]]+ <FUNCTION>/'
por exemplo:
objdump -d main.out | awk -v RS= '/^[[:xdigit:]]+ <myfunc>/'
dá apenas:
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
Ao usar -S
, acho que não há uma maneira à prova de falhas, pois os comentários do código podem conter qualquer sequência possível ... Mas o seguinte funciona quase o tempo todo:
objdump -S main.out | awk '/^[[:xdigit:]]+ <FUNCTION>:$/{flag=1;next}/^[[:xdigit:]]+ <.*>:$/{flag=0}flag'
adaptado de: Como selecionar linhas entre dois padrões de marcadores que podem ocorrer várias vezes com awk / sed
Respostas da lista de discussão
Há um tópico de 2010 na lista de discussão que diz que não é possível: https://sourceware.org/ml/binutils/2010-04/msg00445.html
Além da gdb
solução alternativa proposta por Tom, eles também comentam sobre outra (pior) solução alternativa de compilar, com a -ffunction-section
qual coloca uma função por seção e, em seguida, despeja a seção.
Nicolas Clifton deu a ele um WONTFIX https://sourceware.org/ml/binutils/2015-07/msg00004.html , provavelmente porque a solução alternativa GDB cobre esse caso de uso.
static
, ela pode ser embutida pelo compilador em seus sites de chamada. Isso pode significar que pode não haver nenhuma função para desmontar, por si só . Se você puder localizar símbolos para outras funções, mas não para a função que está procurando, esta é uma forte dica de que a função foi incorporada. Valgrind ainda pode fazer referência à função pré-embutida original porque as informações de depuração do arquivo ELF armazenam de onde cada instrução individual se originou, mesmo se as instruções forem movidas para outro lugar.