Question

Comment lister les symboles exportés à partir d’un fichier .so ?Si possible, j'aimerais également connaître leur source (par ex.s'ils sont extraits d'une bibliothèque statique).

J'utilise gcc 4.0.2, si cela fait une différence.

Était-ce utile?

La solution

L'outil standard pour lister les symboles est nm, vous pouvez l'utiliser simplement comme ceci :

nm -g 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 -gC yourLib.so

Si votre fichier .so est au format elf, vous avez deux options :

Soit objdump (-C est également utile pour démanteler le C++) :

$ objdump -TC libz.so

libz.so:     file format elf64-x86-64

DYNAMIC SYMBOL TABLE:
0000000000002010 l    d  .init  0000000000000000              .init
0000000000000000      DF *UND*  0000000000000000  GLIBC_2.2.5 free
0000000000000000      DF *UND*  0000000000000000  GLIBC_2.2.5 __errno_location
0000000000000000  w   D  *UND*  0000000000000000              _ITM_deregisterTMCloneTable

Ou utiliser readelf:

$ readelf -Ws libz.so
Symbol table '.dynsym' contains 112 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 0000000000002010     0 SECTION LOCAL  DEFAULT   10
     2: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND free@GLIBC_2.2.5 (14)
     3: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __errno_location@GLIBC_2.2.5 (14)
     4: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND _ITM_deregisterTMCloneTable

Autres conseils

Si ton .so Le fichier est au format elf, vous pouvez utiliser le programme readelf pour extraire les informations sur les symboles du binaire.Cette commande vous donnera la table des symboles :

readelf -Ws /usr/lib/libexample.so

Vous ne devez extraire que ceux qui sont définis dans ce .so fichier, pas dans les bibliothèques référencées par celui-ci.Dans ce cas, la septième colonne doit contenir un nombre.Vous pouvez l'extraire en utilisant une simple regex :

readelf -Ws /usr/lib/libstdc++.so.6 | grep '^\([[:space:]]\+[^[:space:]]\+\)\{6\}[[:space:]]\+[[:digit:]]\+'

ou, comme le propose Caspin,:

readelf -Ws /usr/lib/libstdc++.so.6 | awk '{print $8}';
objdump -TC /usr/lib/libexample.so

Pour les bibliothèques partagées libNAME.donc, le commutateur -D était nécessaire pour voir les symboles dans mon Linux

nm -D libNAME.so

et pour la bibliothèque statique comme rapporté par d'autres

nm -g libNAME.a

Je n'arrêtais pas de me demander pourquoi -fvisibilité = caché et #pragma Visibilité GCC ne semblait avoir aucune influence, car tous les symboles étaient toujours visibles avec nm - jusqu'à ce que je trouve ce post qui m'a indiqué lire soi-même et objdump, ce qui m'a fait réaliser qu'il semble y avoir effectivement deux tables de symboles :

  • Celui avec lequel vous pouvez lister nm
  • Celui avec lequel vous pouvez lister lire soi-même et objdump

Je pense que le premier contient des symboles de débogage qui peuvent être supprimés avec bande ou le commutateur -s que vous pouvez donner à l'éditeur de liens ou le installer commande.Et même si nm ne liste plus rien, vos symboles exportés le sont toujours car ils sont dans la "table de symboles dynamiques" ELF, qui est cette dernière.

Essayez d'ajouter -l aux indicateurs 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.

Pour Android .so fichiers, la chaîne d'outils NDK est livrée avec les outils requis mentionnés dans les autres réponses : readelf, objdump et nm.

Pour C++ .so fichiers, le nec plus ultra nm la commande est nm --demangle --dynamic --defined-only --extern-only <my.so>

# nm --demangle --dynamic --defined-only --extern-only /usr/lib64/libqpid-proton-cpp.so | grep work | grep add
0000000000049500 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)

source: https://stackoverflow.com/a/43257338

Vous pouvez utiliser le 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-être objcopy révèle des informations supplémentaires.

/MODIFIER:Le nom de l'outil est bien entendu nm.Le drapeau -g est utilisé pour afficher uniquement les symboles exportés.

nm -g répertorie la variable externe, qui n'est pas nécessairement un 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 pourrez trouver l'adresse par dlsym.

nm --version

GNU nm2.17.50.0.6-12.el5 20061020

Si tu veux juste savoir s'il y a des symboles présent vous pouvez utiliser

objdump -h /path/to/object

ou pour lister les informations de débogage

objdump -g /path/to/object
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top