Wie liste ich die Symbole in einer .so-Datei auf?
-
09-06-2019 - |
Frage
Wie liste ich die Symbole auf, die aus einer .so-Datei exportiert werden?Wenn möglich, würde ich auch gerne deren Quelle wissen (z. B.wenn sie aus einer statischen Bibliothek abgerufen werden).
Ich verwende gcc 4.0.2, falls das einen Unterschied macht.
Lösung
Das Standardtool zum Auflisten von Symbolen ist nm
, Sie können es einfach so verwenden:
nm -g yourLib.so
Wenn Sie Symbole einer C++-Bibliothek sehen möchten, fügen Sie die Option „-C“ hinzu, die die Symbole entschlüsselt (die Entschlüsselung ist weitaus besser lesbar).
nm -gC yourLib.so
Wenn Ihre .so-Datei im Elf-Format vorliegt, haben Sie zwei Möglichkeiten:
Entweder objdump
(-C
ist auch nützlich, um C++ zu entwirren):
$ 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
Oder verwenden 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
Andere Tipps
Wenn dein .so
Da die Datei im Elf-Format vorliegt, können Sie das Programm readelf verwenden, um Symbolinformationen aus der Binärdatei zu extrahieren.Mit diesem Befehl erhalten Sie die Symboltabelle:
readelf -Ws /usr/lib/libexample.so
Sie sollten nur diejenigen extrahieren, die hier definiert sind .so
Datei, nicht in den Bibliotheken, auf die sie verweist.In diesem Fall sollte die siebte Spalte eine Zahl enthalten.Sie können es mit einem einfachen regulären Ausdruck extrahieren:
readelf -Ws /usr/lib/libstdc++.so.6 | grep '^\([[:space:]]\+[^[:space:]]\+\)\{6\}[[:space:]]\+[[:digit:]]\+'
oder, wie vorgeschlagen von Kaspin,:
readelf -Ws /usr/lib/libstdc++.so.6 | awk '{print $8}';
objdump -TC /usr/lib/libexample.so
Für gemeinsam genutzte Bibliotheken libNAME.so war der Schalter -D erforderlich, um Symbole in meinem Linux anzuzeigen
nm -D libNAME.so
und für statische Bibliotheken, wie von anderen berichtet
nm -g libNAME.a
Ich fragte mich immer wieder, warum -fvisibility=versteckt Und #pragma GCC-Sichtbarkeit schien keinen Einfluss zu haben, da alle Symbole immer sichtbar waren nm - bis ich diesen Beitrag fand, der mich darauf hinwies readelf Und objdump, was mir klar machte, dass es tatsächlich so zu sein scheint zwei Symboltabellen:
- Die, mit der Sie auflisten können nm
- Die, mit der Sie auflisten können readelf Und objdump
Ich denke, Ersteres enthält Debugging-Symbole, die entfernt werden können Streifen oder den Schalter -s, den Sie dem Linker oder dem geben können Installieren Befehl.Und selbst wenn nm nichts mehr auflistet, werden Ihre exportierten Symbole trotzdem exportiert, da sie sich in der „dynamischen Symboltabelle“ von ELF befinden, die letztere ist.
Versuchen Sie, -l zu den nm-Flags hinzuzufügen, um die Quelle jedes Symbols zu ermitteln.Wenn die Bibliothek mit Debugging-Informationen (gcc -g) kompiliert wird, sollten dies die Quelldatei und die Zeilennummer sein.Wie Konrad sagte, ist die Objektdatei/statische Bibliothek zu diesem Zeitpunkt wahrscheinlich unbekannt.
Für Android .so
Dateien enthält die NDK-Toolchain die erforderlichen Tools, die in den anderen Antworten erwähnt werden: readelf
, objdump
Und nm
.
Für C++ .so
Dateien, das Nonplusultra nm
Befehl ist 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)
Du kannst den ... benutzen nm -g
Tool aus der Binutils-Toolchain.Ihre Quelle ist jedoch nicht immer leicht verfügbar.und ich bin mir nicht einmal sicher, ob diese Informationen immer abgerufen werden können.Vielleicht objcopy
verrät weitere Informationen.
/BEARBEITEN:Der Name des Tools ist natürlich nm
.Die Flagge -g
wird verwendet, um nur exportierte Symbole anzuzeigen.
nm -g listet die externe Variable auf, bei der es sich nicht um ein exportiertes Symbol handelt.Alle nicht statischen Dateibereichsvariablen (in C) sind alle externe Variablen.
nm -D listet das Symbol in der dynamischen Tabelle auf, deren Adresse Sie über dlsym finden können.
nm --version
GNU nm 2.17.50.0.6-12.el5 20061020
Wenn Sie nur wissen möchten, ob es Symbole gibt gegenwärtig Sie können verwenden
objdump -h /path/to/object
oder um die Debug-Informationen aufzulisten
objdump -g /path/to/object