Comment savoir quels symboles sont exportés à partir d'un objet partagé?

131

J'ai un objet partagé (dll). Comment savoir quels symboles sont exportés à partir de cela?

chappar
la source
1
Tous les symboles de l'objet sont exportés - même les fonctions "internes". Il vous suffit de les déclarer au compilateur afin qu'ils soient prêts pour l'éditeur de liens. Cela se fait généralement avec un fichier d'en-tête, comme Ryan Fox l'a dit ci-dessous.
Chris Lutz
6
Chris Lutz se trompe: tous les symboles ne sont pas exportés à partir de fichiers objets déplaçables, encore moins à partir de bibliothèques partagées.
Employé russe

Réponses:

218

Avez-vous un "objet partagé" (généralement une bibliothèque partagée sous AIX), une bibliothèque partagée UNIX ou une DLL Windows? Ce sont toutes des choses différentes, et votre question les confond toutes :-(

  • Pour un objet partagé AIX, utilisez dump -Tv /path/to/foo.o.
  • Pour une bibliothèque partagée ELF, utilisez readelf -Ws /path/to/libfoo.so, ou (si vous avez GNU nm) nm -D /path/to/libfoo.so.
  • Pour une bibliothèque partagée UNIX non-ELF, veuillez indiquer quel UNIX vous intéresse.
  • Pour une DLL Windows, utilisez dumpbin /EXPORTS foo.dll.
Employé russe
la source
7
Dans GNU / Linux pas un tel utilitaire «dumpbin». Et la question est étiquetée comme linux.
Hi-Angel
3
Très utile, bon d'avoir un tel aperçu. nmfonctionne également sur MacOSX, sauf l' -Doption. Ou brew install binutilset utilisez la version GNU via gnm. Pour GNU nm, --demangleest également utile. Aussi gobjdump.
Albert
En fait, vous pouvez travailler à la fois avec des bibliothèques partagées, des dll et des objets filles à partir d'un seul utilitaire, voir cette réponse .
Hi-Angel
La question est étiquetée, linuxdonc je pense qu'il est prudent de dire que @chappar a une bibliothèque partagée Linux.
jww
Je suppose qu'il n'y a pas d'API pour faire cela au runtime, non? J'ai trouvé que sur Windows, vous avez GetProcAddress () mais vous ne pouvez pas l'utiliser sans exécuter la bibliothèque (ce qui est très dangereux si l'application parente a trop de droits d'accès).
Pablo Ariel
23

objdump est un autre bon sur Linux.

smcameron
la source
Également disponible sur AIX
pitseeker
17

S'il s'agit d'un fichier DLL Windows et que votre système d'exploitation est Linux, utilisez winedump :

$ winedump -j export pcre.dll

Contents of pcre.dll: 229888 bytes

Exports table:

  Name:            pcre.dll
  Characteristics: 00000000
  TimeDateStamp:   53BBA519 Tue Jul  8 10:00:25 2014
  Version:         0.00
  Ordinal base:    1
  # of functions:  31
  # of Names:      31
Addresses of functions: 000375C8
Addresses of name ordinals: 000376C0
Addresses of names: 00037644

  Entry Pt  Ordn  Name
  0001FDA0     1 pcre_assign_jit_stack
  000380B8     2 pcre_callout
  00009030     3 pcre_compile
...
Björn Lindqvist
la source
12

Sur * nix check nm. Sous Windows, utilisez le programme Dependency Walker

AllDayCpp
la source
2
Plus précisément, nm --defined-only -g something.soimprimera les symboles qui sont à la fois définis dans la bibliothèque et les symboles externes, ce qui est probablement ce que souhaite l'OP.
David Grayson
8

voir man nm

GNU nm répertorie les symboles des fichiers objets objfile .... Si aucun fichier objet n'est répertorié comme arguments, nm assume le fichier a.out.
VolkerK
la source
8
btw: pour les objets partagés, vous avez besoin de l'option dynamique -D / -. par exemple nm -D libmagic.so
VolkerK
8

Utilisation: nm --demangle <libname>.so

codebin
la source
2
nm: /usr/lib/i386-linux-gnu/libtemplates_parser.so.11.6: no symbols. readelfou le -Ddrapeau fonctionne.
Janus Troelsen
5

La méthode multiplateforme (non seulement multiplateforme elle-même, mais fonctionnant également, à tout le moins, avec les deux *.soet *.dll) utilise le cadre de rétro-ingénierie radare2 . Par exemple:

$ rabin2 -s glew32.dll | head -n 5 
[Symbols]
vaddr=0x62afda8d paddr=0x0005ba8d ord=000 fwd=NONE sz=0 bind=GLOBAL type=FUNC name=glew32.dll___GLEW_3DFX_multisample
vaddr=0x62afda8e paddr=0x0005ba8e ord=001 fwd=NONE sz=0 bind=GLOBAL type=FUNC name=glew32.dll___GLEW_3DFX_tbuffer
vaddr=0x62afda8f paddr=0x0005ba8f ord=002 fwd=NONE sz=0 bind=GLOBAL type=FUNC name=glew32.dll___GLEW_3DFX_texture_compression_FXT1
vaddr=0x62afdab8 paddr=0x0005bab8 ord=003 fwd=NONE sz=0 bind=GLOBAL type=FUNC name=glew32.dll___GLEW_AMD_blend_minmax_factor

En prime, rabin2reconnaît la modification des noms C ++, par exemple (et aussi avec .sofichier) :

$ rabin2 -s /usr/lib/libabw-0.1.so.1.0.1 | head -n 5
[Symbols]
vaddr=0x00027590 paddr=0x00027590 ord=124 fwd=NONE sz=430 bind=GLOBAL type=FUNC name=libabw::AbiDocument::isFileFormatSupported
vaddr=0x0000a730 paddr=0x0000a730 ord=125 fwd=NONE sz=58 bind=UNKNOWN type=FUNC name=boost::exception::~exception
vaddr=0x00232680 paddr=0x00032680 ord=126 fwd=NONE sz=16 bind=UNKNOWN type=OBJECT name=typeinfoforboost::exception_detail::clone_base
vaddr=0x00027740 paddr=0x00027740 ord=127 fwd=NONE sz=235 bind=GLOBAL type=FUNC name=libabw::AbiDocument::parse

Fonctionne également avec les fichiers objets:

$ g++ test.cpp -c -o a.o
$ rabin2 -s a.o | head -n 5
Warning: Cannot initialize program headers
Warning: Cannot initialize dynamic strings
Warning: Cannot initialize dynamic section
[Symbols]
vaddr=0x08000149 paddr=0x00000149 ord=006 fwd=NONE sz=1 bind=LOCAL type=OBJECT name=std::piecewise_construct
vaddr=0x08000149 paddr=0x00000149 ord=007 fwd=NONE sz=1 bind=LOCAL type=OBJECT name=std::__ioinit
vaddr=0x080000eb paddr=0x000000eb ord=017 fwd=NONE sz=73 bind=LOCAL type=FUNC name=__static_initialization_and_destruction_0
vaddr=0x08000134 paddr=0x00000134 ord=018 fwd=NONE sz=21 bind=LOCAL type=FUNC name=_GLOBAL__sub_I__Z4funcP6Animal
Salut ange
la source
1

Vous pouvez utiliser gnu objdump. objdump -p your.dll. Ensuite .edata, passez au contenu de la section et vous trouverez les fonctions exportées sous [Ordinal/Name Pointer] Table.

Don F
la source
0

Habituellement, vous avez également un fichier d'en-tête que vous incluez dans votre code pour accéder aux symboles.

Ryan Fox
la source