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.

È stato utile?

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)

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

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
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top