J'ai un binaire installé sur mon système et j'aimerais voir le démontage d'une fonction donnée. Utiliser de préférence objdump
, mais d'autres solutions seraient également acceptables.
À partir de ces questions, j'ai appris que je pourrais peut-être démonter une partie du code si je ne connais que les adresses des limites. À partir de cette réponse, j'ai appris à reconvertir mes symboles de débogage fractionnés en un seul fichier.
Mais même en opérant sur ce seul fichier, et même en désassemblant tout le code (c'est-à-dire sans adresse de démarrage ou d'arrêt, mais -d
paramètre clair à objdump
), je ne vois toujours ce symbole nulle part. Ce qui a du sens dans la mesure où la fonction en question est statique, donc elle n'est pas exportée. Néanmoins, valgrind
rapportera le nom de la fonction, il doit donc être stocké quelque part.
En regardant les détails des sections de débogage, je trouve ce nom mentionné dans la .debug_str
section, mais je ne connais pas d'outil qui puisse transformer cela en une plage d'adresses.
static
, elle peut être intégrée par le compilateur dans ses sites d'appels. Cela peut signifier qu'il n'y a peut-être aucune fonction à démonter en soi . Si vous pouvez repérer des symboles pour d'autres fonctions, mais pas la fonction que vous recherchez, cela indique clairement que la fonction a été incorporée. Valgrind peut toujours faire référence à la fonction pré-intégrée d'origine car les informations de débogage du fichier ELF stockent l'origine de chaque instruction individuelle, même si les instructions sont déplacées ailleurs.addr2line
acceptera les PC / IP destdin
et imprimera leurs lignes de code source correspondantes. De même,objdump -l
mélangera l'objdump avec les lignes source; cependant, pour un code hautement optimisé avec une insertion lourde, les résultats de l'un ou l'autre programme ne sont pas toujours particulièrement utiles.Réponses:
Je suggérerais d'utiliser gdb comme approche la plus simple. Vous pouvez même le faire en une seule ligne, comme:
la source
-ex 'command'
n'est pasman gdb
dedans!? Mais est en fait répertorié dans la documentation gdb . Aussi pour d'autres, des trucs comme/bin/ls
peuvent être supprimés, donc si cette commande exacte n'affiche rien, essayez un autre objet! Peut également spécifier un fichier / objet comme argument bareword; par exemple,gdb -batch -ex 'disassemble main' /bin/ls
gdb /bin/ls -batch -ex 'disassemble main'
fonctionne aussicolumn -ts$'\t'
pour filtrer la sortie GDB, vous aurez les octets bruts et les colonnes source bien alignés. En outre,-ex 'set disassembly-flavor intel'
avant que d'autres-ex
s entraînent une syntaxe d'assemblage Intel.disassemble fn
utilisant la méthode ci-dessus. Mais il semble que lorsqu'il y a plusieurs fonctions avec le même nom dans le fichier binaire, une seule est démontée. Est-il possible de tous les démonter ou dois-je les démonter en fonction de l'adresse brute?gdb
disassemble/rs
pour afficher également les octets source et brutsAvec ce format, il se rapproche vraiment de la
objdump -S
sortie:principal c
Compiler et démonter
Démontage:
Testé sur Ubuntu 16.04, GDB 7.11.1.
objdump + awk solutions de contournement
Imprimez le paragraphe comme indiqué sur: /unix/82944/how-to-grep-for-text-in-a-file-and-display-the- paragraph- that - has- the -texte
par exemple:
donne juste:
Lors de l'utilisation
-S
, je ne pense pas qu'il existe un moyen infaillible, car les commentaires de code pourraient contenir n'importe quelle séquence possible ... Mais ce qui suit fonctionne presque tout le temps:adapté de: Comment sélectionner des lignes entre deux motifs de marqueurs qui peuvent se produire plusieurs fois avec awk / sed
Réponses à la liste de diffusion
Il y a un fil de discussion 2010 sur la liste de diffusion qui dit que ce n'est pas possible: https://sourceware.org/ml/binutils/2010-04/msg00445.html
Outre la
gdb
solution de contournement proposée par Tom, ils commentent également une autre (pire) solution de contournement de compilation avec-ffunction-section
laquelle met une fonction par section, puis vidage de la section.Nicolas Clifton lui a donné un WONTFIX https://sourceware.org/ml/binutils/2015-07/msg00004.html , probablement parce que la solution de contournement GDB couvre ce cas d'utilisation.
la source
Démonter une seule fonction à l'aide d'Objdump
J'ai deux solutions:
1. Basé sur la ligne de commande
Cette méthode fonctionne parfaitement et en plus une méthode simple. J'utilise objdump avec le -d drapeau et conduite à travers awk . La sortie démontée ressemble à
Pour commencer, je commence par la description de la sortie objdump. Une section ou une fonction est séparée par une ligne vide. Par conséquent, changer le FS (Field Separator) en newline et le RS (Record Separator) en double newline vous permet de rechercher facilement votre fonction recommandée, car il s'agit simplement de trouver dans le champ $ 1!
Bien sûr, vous pouvez remplacer main par toute autre fonction que vous souhaitez imprimer.
2. Script Bash
J'ai écrit un petit script bash pour ce numéro. Collez-le et copiez-le et enregistrez-le comme par exemple un fichier dasm .
Modifiez l' accès x et invoquez-le avec par exemple:
C'est beaucoup plus rapide que d'appeler gdb avec un script. De plus, utiliser objdump ne chargera pas les bibliothèques en mémoire et est donc plus sûr!
Vitaly Fadeev a programmé une auto-complétion de ce script, ce qui est vraiment une fonctionnalité intéressante et accélère la saisie.
Le script peut être trouvé ici .
la source
objdump
ougdb
est plus rapide. Pour un énorme binaire (libxul.so de Firefox)objdump
prend une éternité, je l'ai annulé après une heure, alors qu'ilgdb
prend moins d'une minute.Pour simplifier l'utilisation de awk pour analyser la sortie d'objdump par rapport aux autres réponses:
la source
Cela fonctionne comme la solution gdb (en ce sens qu'elle décale les décalages vers zéro) sauf que ce n'est pas laggy (fait le travail en environ 5 ms sur mon PC alors que la solution gdb prend environ 150 ms):
objdump_func:
la source
awk
) était la seule fonction du fichier objet, c'est-à-dire que même si la fonction commence à, disons0x2d
, le deuxième awk la déplacera vers0x00
(en soustrayant0x2d
à partir de l'adresse de chaque instruction), ce qui est utile car le code d'assemblage fait souvent des références relatives au début de la fonction et si la fonction commence à 0, vous n'avez pas à faire les soustractions dans votre tête. Le code awk pourrait être meilleur, mais au moins il fait le travail et est assez efficace.-ffunction-sections
est un moyen plus simple de s'assurer que chaque fonction commence à 0.Si vous avez un binutils très récent (2.32+), c'est très simple.
Passer
--disassemble=SYMBOL
à objdump ne démontera que la fonction spécifiée. Pas besoin de passer l'adresse de début et l'adresse de fin.LLVM objdump a également une option similaire (
--disassemble-symbols
).la source
Achèvement de Bash pour
./dasm
Noms des symboles complets pour cette solution (version D lang):
dasm test
puis en appuyant sur TabTab, vous obtiendrez une liste de toutes les fonctions.dasm test m
puis en appuyant sur TabTab toutes les fonctions commençant par m seront affichées, ou dans le cas où une seule fonction existe, elle sera complétée automatiquement.Fichier
/etc/bash_completion.d/dasm
:la source