Come posso elencare i simboli in un file .so


486

Come posso elencare i simboli esportati da un file .so? Se possibile, mi piacerebbe anche conoscere la loro fonte (ad esempio se vengono estratti da una libreria statica).

Sto usando gcc 4.0.2, se questo fa la differenza.


La piattaforma fa la differenza. Apple fornisce un GCC 4.0, ma nmnon risponde ad alcune opzioni, come -De -g(IIRC).
1515

Questo non stampa nulla su Mac OS.
IgorGanapolsky,

3
@jww perché è BSD nm, non GNU nm.
OrangeDog

Risposte:


577

Lo strumento standard per elencare i simboli è nm, puoi usarlo semplicemente in questo modo:

nm -gD yourLib.so

Se vuoi vedere i simboli di una libreria C ++, aggiungi l'opzione "-C" che districa i simboli (è molto più leggibile distrutta).

nm -gDC yourLib.so

Se il tuo file .so è in formato elf, hai due opzioni:

Entrambi objdump( -Cè utile anche per districare 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

Oppure usa 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

35
Tuttavia, ciò non funziona sempre con i file .so, quindi potrebbe essere necessario utilizzare la soluzione "readelf" menzionata in un'altra risposta.
Brooks Moses,

9
Nota che nelle versioni OS X di nm manca l'opzione '-C' per smangiare i simboli. c ++ filt può essere usato invece. Script di esempio qui: v8.googlecode.com/svn/branches/bleeding_edge/tools/mac-nm nm -g /usr/lib/libstdc++.6.dylib | c ++ filt -p -i
fredbaba

5
Nota che readelf -Wsti mostrerà tutti i simboli e nm -gmostrerà solo i simboli visibili esternamente. Questo può essere fonte di confusione se stai esaminando più file di simboli e inizi a scambiare i tuoi comandi.
Andrew B,

3
Vorrei anche aggiungere objectdump -TCall'elenco. Al contrario readelf -Ws, non mostra i nomi alterati.
Yan Foto

2
@BrooksMoses Per i .sofile potrebbe essere necessario aggiungere --dynamicalla nmriga di comando.
user7610

84

Se il tuo .sofile è in formato elfo, puoi utilizzare il programma readelf per estrarre le informazioni sui simboli dal file binario. Questo comando ti darà la tabella dei simboli:

readelf -Ws /usr/lib/libexample.so

È necessario estrarre solo quelli definiti in questo .sofile, non nelle librerie a cui fa riferimento. La settima colonna dovrebbe contenere un numero in questo caso. Puoi estrarlo usando una semplice regex:

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

o, come proposto dalla Caspin ,:

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

19
readelf -Ws /usr/lib/libstdc++.so.6 | awk '{print $ 8}'; le regex sono fantastiche, ma a volte un po 'imbarazzante fa molto.
deft_code


42

Per le librerie condivise libNAME.so il parametro -D era necessario per vedere i simboli nel mio Linux

nm -D libNAME.so

e per la libreria statica come riportato da altri

nm -g libNAME.a

35

Continuavo a chiedermi perché -fvisibilità = nascosto e la visibilità di #pragma GCC non sembravano avere alcuna influenza, poiché tutti i simboli erano sempre visibili con nm - fino a quando non ho trovato questo post che mi ha indicato di leggermi e objdump , che mi ha fatto capire che lì sembrano essere in realtà due tabelle di simboli:

  • Quello che puoi elencare con nm
  • Quello che puoi elencare con readelf e objdump

Penso che il primo contenga simboli di debug che possono essere rimossi con strip o l'opzione -s che puoi dare al linker o al comando di installazione . E anche se nm non elenca più nulla, i simboli esportati vengono comunque esportati perché si trovano nella "tabella dei simboli dinamica" ELF, che è quest'ultima.


3
Grazie! Questo spiega perché a volte "nm" non mostra alcun simbolo per i file .so.
Brooks Moses,

10
nm -D - ti consente di elencare la tabella dei simboli dinamici
pt123

19

Per i .sofile C ++ , il nmcomando finale è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)

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


11

Prova ad aggiungere -l ai flag nm per ottenere l'origine di ciascun simbolo. Se la libreria è compilata con informazioni di debug (gcc -g), questo dovrebbe essere il file sorgente e il numero di riga. Come ha detto Konrad, il file oggetto / libreria statica è probabilmente sconosciuto a questo punto.


11

Per Android .sofile, la toolchain NDK viene fornito con gli strumenti necessari di cui le altre risposte: readelf, objdumpe nm.


9

Puoi usare lo nm -gstrumento dalla toolchain binutils. Tuttavia, la loro fonte non è sempre prontamente disponibile. e non sono nemmeno sicuro che queste informazioni possano sempre essere recuperate. Forse objcopyrivela ulteriori informazioni.

/ EDIT: il nome dello strumento è ovviamente nm. Il flag -gviene utilizzato per mostrare solo i simboli esportati.


6

nm -g elenca la variabile esterna, che non è il simbolo esportato necessario. Qualsiasi variabile di ambito file non statica (in C) è tutta variabile esterna.

nm -D elencherà il simbolo nella tabella dinamica, che puoi trovare il suo indirizzo tramite dlsym.

nm --version

GNU nm 2.17.50.0.6-12.el5 20061020


1

Se vuoi solo sapere se ci sono simboli presenti , puoi usarli

objdump -h /path/to/object

o per elencare le informazioni di debug

objdump -g /path/to/object
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.