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.
nm
, non GNU nm
.
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.
nm
, non GNU nm
.
Risposte:
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
readelf -Ws
ti mostrerà tutti i simboli e nm -g
mostrerà 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.
objectdump -TC
all'elenco. Al contrario readelf -Ws
, non mostra i nomi alterati.
.so
file potrebbe essere necessario aggiungere --dynamic
alla nm
riga di comando.
Se il tuo .so
file è 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 .so
file, 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}';
objdump -TC /usr/lib/libexample.so
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:
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.
Per i .so
file C ++ , il nm
comando 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)
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.
Per Android .so
file, la toolchain NDK viene fornito con gli strumenti necessari di cui le altre risposte: readelf
, objdump
e nm
.
Puoi usare lo nm -g
strumento dalla toolchain binutils. Tuttavia, la loro fonte non è sempre prontamente disponibile. e non sono nemmeno sicuro che queste informazioni possano sempre essere recuperate. Forse objcopy
rivela ulteriori informazioni.
/ EDIT: il nome dello strumento è ovviamente nm
. Il flag -g
viene utilizzato per mostrare solo i simboli esportati.
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
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
nm
non risponde ad alcune opzioni, come-D
e-g
(IIRC).