Recherche d'emplacements dans le code machine (gcc / objdump -d)
-
08-07-2019 - |
Question
Si vous avez à l'esprit une ligne de code C particulière à examiner dans la sortie de la machine, comment la localiseriez-vous dans la sortie objdump. Voici un exemple
if (cond)
foo;
bar();
et je veux voir si la barre était en ligne comme je le voudrais. Ou utiliseriez-vous un autre outil au lieu d’objdump?
La solution
Vous pouvez démarrer objdump en utilisant l'option -S
(comme "quotjdump -Sd a.out" /
). Il affichera le code source mélangé au code assembleur, si les fichiers source à partir desquels le code a été compilé sont disponibles.
Vous pouvez également utiliser la méthode suivante:
int main(void) {
int a = 0;
asm("#");
return a;
}
devient
.file "a.c"
.text
.globl main
.type main, @function
main:
leal 4(%esp), %ecx
andl $-16, %esp
pushl -4(%ecx)
pushl %ebp
movl %esp, %ebp
pushl %ecx
subl $16, %esp
movl <*>, -8(%ebp)
#APP
# 3 "a.c" 1
#
# 0 "" 2
#NO_APP
movl -8(%ebp), %eax
addl $16, %esp
popl %ecx
popl %ebp
leal -4(%ecx), %esp
ret
.size main, .-main
.ident "GCC: (GNU) 4.3.2"
.section .note.GNU-stack,"",@progbits
Autres conseils
Votre débogueur devrait également vous permettre de voir le code source et l'assembly correspondant si vous avez compilé avec des symboles de débogage. C'est l'option gcc -g et la commande gdb disass.
Si vous compilez avec gcc, vous pouvez utiliser -S pour générer directement un fichier d'assemblage. Ce fichier contient généralement des informations utiles, notamment des noms de fonction et parfois des numéros de ligne pour le code (en fonction des options de compilation que vous utilisez).
Les appels de fonction sont détectés dans l'assemblage par le prologue de fonction commun.
Avec i386 c'est
55 push %ebp
89 e5 mov %esp, %ebp
...
c9 leave # optional
c3 ret
avec amd64 / x86_64 est similaire (le préfixe du quad 48
):
55 push %rbp
48 89 e5 mov %rsp,%rbp
..
c9 leaveq # optional
c3 retq
Donc, quand vous détectez cela dans votre objdump -S bla.o
ou
gcc bla.c -g -fsave-temps -fverbose-asm
sortie de votre fonction principale
et pour bar aussi, bar n'est pas en ligne. Aussi quand principal a un appel ou un saut
barrer n'est pas en ligne.
Dans votre cas, vous pourriez voir si le bar a des vars locaux, ce qui nécessite de la place sur
la pile locale. Si barre est en ligne, le réglage de la pile (par exemple, sous $ 0x8,% esp
)
est fait juste après le prologue principal, main pourrait accéder à var.
Si ce n’est pas le cas, c’est privé de barrer.