Wie liste ich die Symbole in einer .so-Datei auf?

486

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.

Moe
quelle
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:    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
Steve Gury
quelle
35
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:

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

oder, wie von Caspin vorgeschlagen ,:

readelf -Ws /usr/lib/libstdc++.so.6 | awk '{print $8}';
P Shved
quelle
19
readelf -Ws /usr/lib/libstdc++.so.6 | awk '{print $ 8}'; Regexes sind fantastisch, aber manchmal reicht ein wenig Awk aus.
Deft_code
55
objdump -TC /usr/lib/libexample.so
Pavel Lapin
quelle
42

Für gemeinsam genutzte Bibliotheken libNAME.so war der Schalter -D erforderlich, um Symbole in meinem Linux zu sehen

nm -D libNAME.so

und für statische Bibliothek, wie von anderen berichtet

nm -g libNAME.a
Cavila
quelle
35

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.

Peter Remmers
quelle
3
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 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)

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

user7610
quelle
11

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.

Adam Mitz
quelle
11

Für Android - .soDateien kommt das NDK mit Werkzeugkette die benötigten Werkzeuge in den anderen Antworten erwähnt: readelf, objdumpund nm.

Adi Shavit
quelle
9

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.

Konrad Rudolph
quelle
6

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

zhaorufei
quelle
1

Wenn Sie nur wissen möchten, ob Symbole vorhanden sind , können Sie diese verwenden

objdump -h /path/to/object

oder um die Debug-Informationen aufzulisten

objdump -g /path/to/object
Craig Ringer
quelle