Come elenco i simboli in un file .so
-
09-06-2019 - |
Domanda
Come posso elencare i simboli esportati da un file .so?Se possibile, mi piacerebbe anche conoscerne la fonte (es.se vengono estratti da una libreria statica).
Sto usando gcc 4.0.2, se questo fa la differenza.
Soluzione
Lo strumento standard per elencare i simboli è nm
, puoi usarlo semplicemente in questo modo:
nm -g yourLib.so
Se vuoi vedere i simboli di una libreria C++, aggiungi l'opzione "-C" che smantella i simboli (è molto più leggibile smantellata).
nm -gC yourLib.so
Se il tuo file .so è in formato elf, hai due opzioni:
O objdump
(-C
è utile anche per scomporre il 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 utilizzare 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
Altri suggerimenti
Se tuo .so
il file è in formato elf, puoi utilizzare il programma readelf per estrarre le informazioni sui simboli dal binario.Questo comando ti darà la tabella dei simboli:
readelf -Ws /usr/lib/libexample.so
Dovresti estrarre solo quelli definiti in questo .so
file, non nelle librerie a cui fa riferimento.La settima colonna dovrebbe contenere un numero in questo caso.Puoi estrarlo utilizzando una semplice regex:
readelf -Ws /usr/lib/libstdc++.so.6 | grep '^\([[:space:]]\+[^[:space:]]\+\)\{6\}[[:space:]]\+[[:digit:]]\+'
o, come proposto da Caspino,:
readelf -Ws /usr/lib/libstdc++.so.6 | awk '{print $8}';
objdump -TC /usr/lib/libexample.so
Per le librerie condivise libNAME.so l'opzione -D era necessaria per vedere i simboli nel mio Linux
nm -D libNAME.so
e per la libreria statica come riportato da altri
nm -g libNAME.a
Continuavo a chiedermi perché -fvisibilità=nascosto E #pragma Visibilità del GCC non sembrava avere alcuna influenza, poiché tutti i simboli erano sempre visibili nm - finché non ho trovato questo post che mi indicava readef E objdump, il che mi ha fatto capire che sembra esserci effettivamente due tabelle dei simboli:
- Quello con cui puoi elencare nm
- Quello con cui puoi elencare readef E objdump
Penso che il primo contenga simboli di debug con cui è possibile eliminare striscia o l'opzione -s che puoi dare al linker o al installare comando.E anche se nm non elenca più nulla, i tuoi simboli esportati vengono comunque esportati perché si trovano nella "tabella dei simboli dinamici" ELF, che è quest'ultima.
Prova ad aggiungere -l ai flag nm per ottenere la fonte 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.
Per Android .so
file, la toolchain NDK viene fornita con gli strumenti richiesti menzionati nelle altre risposte: readelf
, objdump
E nm
.
Per C++ .so
file, il massimo nm
il comando è 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)
Puoi usare il nm -g
strumento dalla toolchain binutils.Tuttavia, la loro fonte non è sempre facilmente disponibile.e in realtà non sono nemmeno sicuro che queste informazioni possano sempre essere recuperate.Forse objcopy
rivela ulteriori informazioni.
/MODIFICARE:Il nome dello strumento è ovviamente nm
.La bandiera -g
viene utilizzato per mostrare solo i simboli esportati.
nm -g elenca la variabile extern, che non è necessariamente il simbolo esportato.Qualsiasi variabile di ambito file non statica (in C) è tutta variabile esterna.
nm -D elencherà il simbolo nella tabella dinamica, di cui puoi trovare l'indirizzo tramite dlsym.
nm --versione
GNU nm 2.17.50.0.6-12.el5 20061020
Se vuoi solo sapere se ci sono simboli presente Puoi usare
objdump -h /path/to/object
o per elencare le informazioni di debug
objdump -g /path/to/object