Comment répertorier les symboles dans un fichier .so
486
Comment répertorier les symboles exportés à partir d'un fichier .so? Si possible, j'aimerais également connaître leur source (par exemple, s'ils sont extraits d'une bibliothèque statique).
La plateforme fait la différence. Apple fournit un GCC 4.0, mais son nmne répond pas à certaines options, comme -Det -g(IIRC).
2015
Cela n'imprime rien sur Mac OS.
IgorGanapolsky
3
@jww parce que c'est BSD nm, pas GNU nm.
OrangeDog du
Réponses:
577
L'outil standard pour lister les symboles est nm, vous pouvez l'utiliser simplement comme ceci:
nm -gD yourLib.so
Si vous voulez voir les symboles d'une bibliothèque C ++, ajoutez l'option "-C" qui démêle les symboles (c'est beaucoup plus lisible démêlé).
nm -gDC yourLib.so
Si votre fichier .so est au format elf, vous avez deux options:
Soit objdump( -Cest également utile pour démêler C ++):
$ objdump -TC libz.so
libz.so: file format elf64-x86-64
DYNAMIC SYMBOL TABLE:0000000000002010 l d .init 0000000000000000.init0000000000000000 DF *UND*0000000000000000 GLIBC_2.2.5 free0000000000000000 DF *UND*0000000000000000 GLIBC_2.2.5 __errno_location0000000000000000 w D *UND*0000000000000000 _ITM_deregisterTMCloneTable
Ou utilisez readelf:
$ readelf -Ws libz.soSymbol table '.dynsym' contains 112 entries:Num:ValueSizeTypeBindVisNdxName0:00000000000000000 NOTYPE LOCAL DEFAULT UND1:00000000000020100 SECTION LOCAL DEFAULT 102:00000000000000000 FUNC GLOBAL DEFAULT UND free@GLIBC_2.2.5(14)3:00000000000000000 FUNC GLOBAL DEFAULT UND __errno_location@GLIBC_2.2.5(14)4:00000000000000000 NOTYPE WEAK DEFAULT UND _ITM_deregisterTMCloneTable
Cela ne fonctionne pas toujours avec les fichiers .so, cependant, et vous devrez donc peut-être utiliser la solution "readelf" mentionnée dans une autre réponse.
Brooks Moses
9
Notez que les versions OS X de nm n'ont pas l'option «-C» pour démêler les symboles. c ++ filt peut être utilisé à la place. Exemple de script ici: v8.googlecode.com/svn/branches/bleeding_edge/tools/mac-nm nm -g /usr/lib/libstdc++.6.dylib | c ++ filt -p -i
fredbaba
5
Notez que readelf -Wscela vous montrera tous les symboles et nm -gne montrera que les symboles visibles de l'extérieur. Cela peut être déroutant si vous examinez plusieurs fichiers de symboles et commencez à échanger vos commandes.
Andrew B
3
J'ajouterais également objectdump -TCà la liste. Contrairement à readelf -Ws, il ne montre pas les noms mutilés.
Yan Foto
2
@BrooksMoses Pour les .sofichiers, vous devrez peut-être ajouter --dynamicà la nmligne de commande.
user7610
84
Si votre .sofichier est au format elf, vous pouvez utiliser le programme readelf pour extraire les informations de symbole du binaire. Cette commande vous donnera la table des symboles:
readelf -Ws/usr/lib/libexample.so
Vous devez uniquement extraire ceux qui sont définis dans ce .sofichier, pas dans les bibliothèques référencées par celui-ci. La septième colonne doit contenir un nombre dans ce cas. Vous pouvez l'extraire à l'aide d'une expression régulière simple:
Je me demandais pourquoi -fvisibility = caché et la visibilité #pragma GCC ne semblait pas avoir d'influence, car tous les symboles étaient toujours visibles avec nm - jusqu'à ce que je trouve ce post qui me dirigeait vers readelf et objdump , ce qui m'a fait réaliser qu'il y avait semblent en fait être deux tables de symboles:
Celui que vous pouvez lister avec nm
Celui que vous pouvez lister avec readelf et objdump
Je pense que le premier contient des symboles de débogage qui peuvent être supprimés avec strip ou le commutateur -s que vous pouvez donner à l'éditeur de liens ou à la commande d' installation . Et même si nm ne répertorie plus rien, vos symboles exportés sont toujours exportés car ils se trouvent dans la "table des symboles dynamiques" ELF, qui est la dernière.
Je vous remercie! Cela explique pourquoi parfois "nm" n'affiche aucun symbole pour les fichiers .so.
Brooks Moses
10
nm -D - vous permet de lister la table des symboles dynamiques
pt123
19
Pour les .sofichiers C ++ , la nmcommande ultime estnm --demangle --dynamic --defined-only --extern-only <my.so>
# nm --demangle --dynamic --defined-only --extern-only /usr/lib64/libqpid-proton-cpp.so | grep work | grep add0000000000049500 T proton::work_queue::add(proton::internal::v03::work)0000000000049580 T proton::work_queue::add(proton::void_function0&)000000000002e7b0 W proton::work_queue::impl::add_void(proton::internal::v03::work)000000000002b1f0 T proton::container::impl::add_work_queue()000000000002dc50 T proton::container::impl::container_work_queue::add(proton::internal::v03::work)000000000002db60 T proton::container::impl::connection_work_queue::add(proton::internal::v03::work)
Essayez d'ajouter -l aux drapeaux nm afin d'obtenir la source de chaque symbole. Si la bibliothèque est compilée avec des informations de débogage (gcc -g), il doit s'agir du fichier source et du numéro de ligne. Comme l'a dit Konrad, le fichier objet / bibliothèque statique est probablement inconnu à ce stade.
Vous pouvez utiliser l' nm -goutil de la chaîne d'outils binutils. Cependant, leur source n'est pas toujours facilement disponible. et je ne suis même pas sûr que ces informations puissent toujours être récupérées. Peut-être objcopyrévèle des informations supplémentaires.
/ EDIT: Le nom de l'outil est bien sûr nm. Le drapeau -gest utilisé pour afficher uniquement les symboles exportés.
nm -g liste la variable externe, qui n'est pas nécessairement le symbole exporté. Toutes les variables de portée de fichier non statiques (en C) sont toutes des variables externes.
nm -D listera le symbole dans le tableau dynamique, dont vous pouvez trouver l'adresse par dlsym.
nm
ne répond pas à certaines options, comme-D
et-g
(IIRC).nm
, pas GNUnm
.Réponses:
L'outil standard pour lister les symboles est
nm
, vous pouvez l'utiliser simplement comme ceci:Si vous voulez voir les symboles d'une bibliothèque C ++, ajoutez l'option "-C" qui démêle les symboles (c'est beaucoup plus lisible démêlé).
Si votre fichier .so est au format elf, vous avez deux options:
Soit
objdump
(-C
est également utile pour démêler C ++):Ou utilisez
readelf
:la source
readelf -Ws
cela vous montrera tous les symboles etnm -g
ne montrera que les symboles visibles de l'extérieur. Cela peut être déroutant si vous examinez plusieurs fichiers de symboles et commencez à échanger vos commandes.objectdump -TC
à la liste. Contrairement àreadelf -Ws
, il ne montre pas les noms mutilés..so
fichiers, vous devrez peut-être ajouter--dynamic
à lanm
ligne de commande.Si votre
.so
fichier est au format elf, vous pouvez utiliser le programme readelf pour extraire les informations de symbole du binaire. Cette commande vous donnera la table des symboles:Vous devez uniquement extraire ceux qui sont définis dans ce
.so
fichier, pas dans les bibliothèques référencées par celui-ci. La septième colonne doit contenir un nombre dans ce cas. Vous pouvez l'extraire à l'aide d'une expression régulière simple:ou, tel que proposé par Caspin ,:
la source
la source
Pour les bibliothèques partagées libNAME.so, le commutateur -D était nécessaire pour voir les symboles dans mon Linux
et pour la bibliothèque statique tel que rapporté par d'autres
la source
Je me demandais pourquoi -fvisibility = caché et la visibilité #pragma GCC ne semblait pas avoir d'influence, car tous les symboles étaient toujours visibles avec nm - jusqu'à ce que je trouve ce post qui me dirigeait vers readelf et objdump , ce qui m'a fait réaliser qu'il y avait semblent en fait être deux tables de symboles:
Je pense que le premier contient des symboles de débogage qui peuvent être supprimés avec strip ou le commutateur -s que vous pouvez donner à l'éditeur de liens ou à la commande d' installation . Et même si nm ne répertorie plus rien, vos symboles exportés sont toujours exportés car ils se trouvent dans la "table des symboles dynamiques" ELF, qui est la dernière.
la source
Pour les
.so
fichiers C ++ , lanm
commande ultime estnm --demangle --dynamic --defined-only --extern-only <my.so>
source: https://stackoverflow.com/a/43257338
la source
Essayez d'ajouter -l aux drapeaux nm afin d'obtenir la source de chaque symbole. Si la bibliothèque est compilée avec des informations de débogage (gcc -g), il doit s'agir du fichier source et du numéro de ligne. Comme l'a dit Konrad, le fichier objet / bibliothèque statique est probablement inconnu à ce stade.
la source
Pour Android
.so
fichiers, l'ensemble des outils NDK est livré avec les outils nécessaires mentionnés dans les autres réponses:readelf
,objdump
etnm
.la source
Vous pouvez utiliser l'
nm -g
outil de la chaîne d'outils binutils. Cependant, leur source n'est pas toujours facilement disponible. et je ne suis même pas sûr que ces informations puissent toujours être récupérées. Peut-êtreobjcopy
révèle des informations supplémentaires./ EDIT: Le nom de l'outil est bien sûr
nm
. Le drapeau-g
est utilisé pour afficher uniquement les symboles exportés.la source
nm -g liste la variable externe, qui n'est pas nécessairement le symbole exporté. Toutes les variables de portée de fichier non statiques (en C) sont toutes des variables externes.
nm -D listera le symbole dans le tableau dynamique, dont vous pouvez trouver l'adresse par dlsym.
nm --version
GNU nm 2.17.50.0.6-12.el5 20061020
la source
Si vous voulez juste savoir s'il y a des symboles présents , vous pouvez utiliser
ou pour lister les informations de débogage
la source