Wie liste ich die Symbole auf, die aus einer .so-Datei exportiert werden? Wenn möglich, möchte ich auch ihre Quelle kennen (z. B. wenn sie aus einer statischen Bibliothek abgerufen werden).
Ich benutze gcc 4.0.2, wenn das einen Unterschied macht.
Die Plattform macht einen Unterschied. Apple bietet ein GCC 4.0 an, nmreagiert jedoch nicht auf einige Optionen wie -Dund -g(IIRC).
JWW
Dies druckt nichts unter Mac OS.
IgorGanapolsky
3
@jww weil das BSD ist nm, nicht GNU nm.
OrangeDog
Antworten:
576
Das Standardwerkzeug zum Auflisten von Symbolen ist nm, Sie können es einfach so verwenden:
nm -gD yourLib.so
Wenn Sie Symbole einer C ++ - Bibliothek anzeigen möchten, fügen Sie die Option "-C" hinzu, mit der die Symbole entwirrt werden (die Lesbarkeit ist weitaus besser lesbar).
nm -gDC yourLib.so
Wenn Ihre .so-Datei im Elf-Format vorliegt, haben Sie zwei Möglichkeiten:
Entweder objdump( -Cist 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 Sie readelf:
$ readelf -Ws libz.so
Symbol table '.dynsym' contains 112 entries:Num:ValueSizeTypeBindVisNdxName0:00000000000000000 NOTYPE LOCAL DEFAULT UND
1: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
Dies funktioniert jedoch nicht immer mit .so-Dateien. Daher müssen Sie möglicherweise die in einer anderen Antwort erwähnte "readelf" -Lösung verwenden.
Brooks Moses
9
Beachten Sie, dass in OS X-Versionen von nm die Option '-C' zum Entwirren von Symbolen fehlt. Stattdessen kann c ++ filt verwendet werden. Beispielskript hier: v8.googlecode.com/svn/branches/bleeding_edge/tools/mac-nm nm -g /usr/lib/libstdc++.6.dylib | c ++ filt -p -i
fredbaba
5
Beachten Sie, dass readelf -WsIhnen alle Symbole und nm -gnur die von außen sichtbaren Symbole angezeigt werden. Dies kann verwirrend sein, wenn Sie mehrere Symboldateien untersuchen und Ihre Befehle austauschen.
Andrew B
3
Ich würde auch objectdump -TCzur Liste hinzufügen . Im Gegensatz dazu readelf -Wswerden die verstümmelten Namen nicht angezeigt.
Yan Foto
2
@BrooksMoses Für .soDateien, die Sie möglicherweise --dynamiczur nmBefehlszeile hinzufügen müssen .
user7610
84
Wenn Ihre .soDatei im Elf-Format vorliegt, können Sie das Readelf-Programm verwenden, um Symbolinformationen aus der Binärdatei zu extrahieren. Dieser Befehl gibt Ihnen die Symboltabelle:
readelf -Ws/usr/lib/libexample.so
Sie sollten nur diejenigen extrahieren, die in dieser .soDatei definiert sind , nicht in den Bibliotheken, auf die sie verweist. Die siebte Spalte sollte in diesem Fall eine Nummer enthalten. Sie können es mit einem einfachen regulären Ausdruck extrahieren:
Ich fragte mich immer wieder, warum -fvisibility = hidden und #pragma GCC-Sichtbarkeit keinen Einfluss zu haben schien, da alle Symbole immer mit nm sichtbar waren - bis ich diesen Beitrag fand, der mich auf readelf und objdump hinwies , was mir das klar machte scheinen tatsächlich zwei Symboltabellen zu sein:
Die, die Sie mit nm auflisten können
Die, die Sie mit readelf und objdump auflisten können
Ich denke, Ersteres enthält Debugging-Symbole, die mit Strip oder dem Schalter -s entfernt werden können, den Sie dem Linker oder dem Installationsbefehl geben können . Und selbst wenn nm nichts mehr auflistet, werden Ihre exportierten Symbole trotzdem exportiert, da sie sich in der "dynamischen Symboltabelle" der ELF befinden.
Vielen Dank! Dies erklärt, warum "nm" manchmal keine Symbole für .so-Dateien anzeigt.
Brooks Moses
10
nm -D - lässt Sie die dynamische Symboltabelle
auflisten
19
Für C ++ - .soDateien nmlautet der ultimative Befehlnm --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)
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 wurde, sollte dies die Quelldatei und die Zeilennummer sein. Wie Konrad sagte, ist die Objektdatei / statische Bibliothek zu diesem Zeitpunkt wahrscheinlich unbekannt.
Sie können das nm -gTool aus der binutils-Toolchain verwenden. Ihre Quelle ist jedoch nicht immer leicht verfügbar. und ich bin mir nicht mal sicher, ob diese Informationen immer abgerufen werden können. Vielleicht objcopyenthüllt weitere Informationen.
/ EDIT: Der Name des Tools ist natürlich nm. Das Flag -gwird verwendet, um nur exportierte Symbole anzuzeigen.
nm -g listet die externe Variable auf, für die kein exportiertes Symbol erforderlich ist. Alle nicht statischen Variablen für den Dateibereich (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
reagiert jedoch nicht auf einige Optionen wie-D
und-g
(IIRC).nm
, nicht GNUnm
.Antworten:
Das Standardwerkzeug zum Auflisten von Symbolen ist
nm
, Sie können es einfach so verwenden:Wenn Sie Symbole einer C ++ - Bibliothek anzeigen möchten, fügen Sie die Option "-C" hinzu, mit der die Symbole entwirrt werden (die Lesbarkeit ist weitaus besser lesbar).
Wenn Ihre .so-Datei im Elf-Format vorliegt, haben Sie zwei Möglichkeiten:
Entweder
objdump
(-C
ist auch nützlich, um C ++ zu entwirren):Oder verwenden Sie
readelf
:quelle
readelf -Ws
Ihnen alle Symbole undnm -g
nur die von außen sichtbaren Symbole angezeigt werden. Dies kann verwirrend sein, wenn Sie mehrere Symboldateien untersuchen und Ihre Befehle austauschen.objectdump -TC
zur Liste hinzufügen . Im Gegensatz dazureadelf -Ws
werden die verstümmelten Namen nicht angezeigt..so
Dateien, die Sie möglicherweise--dynamic
zurnm
Befehlszeile hinzufügen müssen .Wenn Ihre
.so
Datei im Elf-Format vorliegt, können Sie das Readelf-Programm verwenden, um Symbolinformationen aus der Binärdatei zu extrahieren. Dieser Befehl gibt Ihnen die Symboltabelle:Sie sollten nur diejenigen extrahieren, die in dieser
.so
Datei definiert sind , nicht in den Bibliotheken, auf die sie verweist. Die siebte Spalte sollte in diesem Fall eine Nummer enthalten. Sie können es mit einem einfachen regulären Ausdruck extrahieren:oder, wie von Caspin vorgeschlagen ,:
quelle
quelle
Für gemeinsam genutzte Bibliotheken libNAME.so war der Schalter -D erforderlich, um Symbole in meinem Linux zu sehen
und für statische Bibliothek, wie von anderen berichtet
quelle
Ich fragte mich immer wieder, warum -fvisibility = hidden und #pragma GCC-Sichtbarkeit keinen Einfluss zu haben schien, da alle Symbole immer mit nm sichtbar waren - bis ich diesen Beitrag fand, der mich auf readelf und objdump hinwies , was mir das klar machte scheinen tatsächlich zwei Symboltabellen zu sein:
Ich denke, Ersteres enthält Debugging-Symbole, die mit Strip oder dem Schalter -s entfernt werden können, den Sie dem Linker oder dem Installationsbefehl geben können . Und selbst wenn nm nichts mehr auflistet, werden Ihre exportierten Symbole trotzdem exportiert, da sie sich in der "dynamischen Symboltabelle" der ELF befinden.
quelle
Für C ++ -
.so
Dateiennm
lautet der ultimative Befehlnm --demangle --dynamic --defined-only --extern-only <my.so>
Quelle: https://stackoverflow.com/a/43257338
quelle
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 wurde, sollte dies die Quelldatei und die Zeilennummer sein. Wie Konrad sagte, ist die Objektdatei / statische Bibliothek zu diesem Zeitpunkt wahrscheinlich unbekannt.
quelle
Für Android -
.so
Dateien kommt das NDK mit Werkzeugkette die benötigten Werkzeuge in den anderen Antworten erwähnt:readelf
,objdump
undnm
.quelle
Sie können das
nm -g
Tool aus der binutils-Toolchain verwenden. Ihre Quelle ist jedoch nicht immer leicht verfügbar. und ich bin mir nicht mal sicher, ob diese Informationen immer abgerufen werden können. Vielleichtobjcopy
enthüllt weitere Informationen./ EDIT: Der Name des Tools ist natürlich
nm
. Das Flag-g
wird verwendet, um nur exportierte Symbole anzuzeigen.quelle
nm -g listet die externe Variable auf, für die kein exportiertes Symbol erforderlich ist. Alle nicht statischen Variablen für den Dateibereich (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
quelle
Wenn Sie nur wissen möchten, ob Symbole vorhanden sind , können Sie diese verwenden
oder um die Debug-Informationen aufzulisten
quelle