Commande Linux nm
nmIl s'agit d'un outil de ligne de commande important dans les systèmes Linux, dont le nom complet est « Name List ». Il est utilisé pour afficher les informations de symboles dans les fichiers objets binaires (tels que les fichiers de bibliothèque et les exécutables), et c'est un outil courant pour les programmeurs et pour l'analyse des fichiers binaires.
Fonctionnalités principales
- Lister les symboles (fonctions, variables, etc.) dans les fichiers objets
- Afficher les types et attributs des symboles
- Aider à analyser les problèmes de liaison des programmes
- Aider au débogage et à la rétro-ingénierie
Syntaxe de base
nm [选项] 文件名
Paramètres d'option courants
| Option | Description |
|---|---|
-a |
Afficher tous les symboles, y compris les symboles de débogage |
-g |
Afficher uniquement les symboles externes (globaux) |
-u |
Afficher uniquement les symboles non définis |
-D |
Afficher les symboles dynamiques (pour les bibliothèques partagées) |
-C |
Démangler les noms de symboles C++ |
-l |
Afficher les numéros de ligne où se trouvent les symboles (nécessite des informations de débogage) |
-S |
Afficher la taille des symboles |
-t |
Spécifier le format de sortie (d-décimal, o-octal, x-hexadécimal) |
--size-sort |
Trier par taille de symbole |
--defined-only |
Afficher uniquement les symboles définis |
Description du type de symbole
nmLe type de symbole dans la sortie est représenté par une lettre ; les plus courants sont :
| Type | Description |
|---|---|
| A | Symbole absolu, non modifié lors de l'édition de liens |
| B/b | Symbole dans le segment de données non initialisées (segment BSS) |
| D/d | Symbole dans le segment de données initialisées |
| T/t | Symbole dans le segment de code (T pour global, t pour local) |
| U | Symbole non défini (doit être lié depuis d'autres fichiers) |
| W/w | Symbole faible |
| R/r | Symbole dans le segment de données en lecture seule |
| C | Symbole commun |
| I | Référence indirecte à un autre symbole |
Exemples d'applications pratiques
Exemple 1 : Afficher la table des symboles d'un fichier exécutable
nm /bin/ls
Exemple de sortie :
0000000000000000 A _IO_stdin_used 0000000000000000 R _fp_hw 0000000000000000 T _init 0000000000000000 W _ITM_deregisterTMCloneTable 0000000000000000 W _ITM_registerTMCloneTable 0000000000000000 W __cxa_finalize 0000000000000000 W __gmon_start__ 0000000000000000 T __libc_csu_fini 0000000000000000 T __libc_csu_init ...
Exemple 2 : Afficher uniquement les symboles non définis
nm -u /bin/ls
Exemple de sortie :
U __ctype_toupper_loc
U __errno_location
U __overflow
U __stack_chk_fail
U __strtoul_internal
U _obstack_begin
U _obstack_newchunk
U abort
U access
...
Exemple 3 : Afficher les symboles d'un programme C++ (noms démanglés)
nm -C my_program
Exemple de sortie :
0000000000000000 T main 0000000000000000 T std::cout 0000000000000000 T std::basic_ostream<char, std::char_traits >& std::operator<< <std::char_traits >(std::basic_ostream<char, std::char_traits >&, char const*) ...
Exemple 4 : Afficher les tailles des symboles et trier par taille
nm -S --size-sort my_library.so
Exemple de sortie :
0000000000000001 0000000000000001 T func1 0000000000000002 0000000000000002 T func2 0000000000000004 0000000000000004 D global_var 0000000000000008 0000000000000008 B large_buffer ...
Cas d'utilisation courants
1. Résolution des erreurs de liaison
Lorsque vous rencontrez une erreur « undefined reference », vous pouvez utilisernmVérifier quels symboles sont indéfinis :
nm -u my_program.o
2. Analyse du contenu des fichiers de bibliothèque
Afficher les symboles exportés par une bibliothèque partagée :
nm -D libexample.so
3. Comparaison de deux versions d'un fichier binaire
Exemple
nm new_version > new.txt
diff old.txt new.txt
4. Recherche de symboles spécifiques
nm my_program | grep "main"
Notes
- Pour les fichiers binaires dépouillés,
nmles informations utiles peuvent ne pas être affichées - Les fichiers binaires d'architectures différentes peuvent nécessiter d'utiliser celui de la chaîne d'outils de compilation croisée
nm - Les symboles dynamiques (dans les bibliothèques partagées) doivent être consultés à l'aide de la
-Doption pour visualiser - Pour les programmes C++, il est recommandé de toujours utiliser l'
-Coption pour démangler les noms de symboles
Astuces avancées
Combinaison avec d'autres outils
Exemple
objdump -t my_program
# Utiliser readelf pour afficher les informations d'en-tête du fichier ELF
readelf -s my_program
Écrire des scripts pour analyser les symboles
Exemple
# Compter la distribution des types de symboles
nm $1 | awk '{print $2}' | sort | uniq -c | sort -nr
Création de fichiers de mappage de symboles
nm -n my_program > symbol_map.txt
Résumé
nmLa commande est l'un des outils importants pour les développeurs Linux. La maîtriser vous permet de :
- Mieux comprendre la structure du programme
- Localiser rapidement les problèmes d'édition de liens
- Analyser le contenu des bibliothèques tierces
- Aider au débogage et à la rétro-ingénierie
Grâce à l'utilisation de base et aux exemples pratiques présentés dans cet article, vous devriez avoir maîtrisé lanmfonctionnalité principale de la commande. Dans le travail réel, vous pouvez utiliser de manière flexible diverses options et paramètres en fonction de besoins spécifiques.
Autres extensions
Référence des commandes Linux