Pregunta

¿Cómo enumero los símbolos que se exportan desde un archivo .so?Si es posible, también me gustaría saber su fuente (p. ej.si se extraen de una biblioteca estática).

Estoy usando gcc 4.0.2, si eso hace la diferencia.

¿Fue útil?

Solución

La herramienta estándar para enumerar símbolos es nm, puedes usarlo simplemente así:

nm -g yourLib.so

Si desea ver los símbolos de una biblioteca C++, agregue la opción "-C" que exige los símbolos (es mucho más legible).

nm -gC yourLib.so

Si su archivo .so está en formato elf, tiene dos opciones:

Cualquiera objdump (-C También es útil para controlar 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

O usar 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

Otros consejos

Si tu .so El archivo está en formato elf, puede usar el programa readelf para extraer información de símbolos del binario.Este comando le dará la tabla de símbolos:

readelf -Ws /usr/lib/libexample.so

Sólo debes extraer aquellos que están definidos en este .so archivo, no en las bibliotecas a las que hace referencia.En este caso, la séptima columna debe contener un número.Puedes extraerlo usando una expresión regular simple:

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

o, como lo propone caspin,:

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

Para las bibliotecas compartidas libNAME.so, el modificador -D era necesario para ver los símbolos en mi Linux

nm -D libNAME.so

y para la biblioteca estática según lo informado por otros

nm -g libNAME.a

Me seguía preguntando por qué -fvisibilidad=oculto y #pragma Visibilidad del CCG no pareció tener ninguna influencia, ya que todos los símbolos siempre estaban visibles con Nuevo Méjico - hasta que encontré esta publicación que me señaló lectura y volcado de objetos, lo que me hizo darme cuenta de que en realidad parece haber dos tablas de símbolos:

  • Con el que puedes listar Nuevo Méjico
  • Con el que puedes listar lectura y volcado de objetos

Creo que el primero contiene símbolos de depuración que se pueden eliminar con banda o el modificador -s que puedes darle al enlazador o al instalar dominio.E incluso si nm ya no incluye nada, sus símbolos exportados aún se exportan porque están en la "tabla de símbolos dinámicos" de ELF, que es la última.

Intente agregar -l a los indicadores nm para obtener la fuente de cada símbolo.Si la biblioteca está compilada con información de depuración (gcc -g), este debería ser el archivo fuente y el número de línea.Como dijo Konrad, el archivo objeto/biblioteca estática probablemente se desconozca en este momento.

Para Android .so archivos, la cadena de herramientas NDK viene con las herramientas necesarias mencionadas en las otras respuestas: readelf, objdump y nm.

Para C++ .so archivos, lo último nm el comando es 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)

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

Puedes usar el nm -g herramienta de la cadena de herramientas binutils.Sin embargo, su fuente no siempre está disponible.y ni siquiera estoy seguro de que esta información siempre pueda recuperarse.Tal vez objcopy revela más información.

/EDITAR:El nombre de la herramienta es, por supuesto. nm.La bandera -g se utiliza para mostrar solo símbolos exportados.

nm -g enumera la variable externa, que no es necesario el símbolo exportado.Cualquier variable de alcance de archivo no estático (en C) es una variable externa.

nm -D enumerará el símbolo en la tabla dinámica, cuya dirección puede encontrar mediante dlsym.

nm --versión

GNU nm 2.17.50.0.6-12.el5 20061020

Si solo quieres saber si hay símbolos presente puedes usar

objdump -h /path/to/object

o para enumerar la información de depuración

objdump -g /path/to/object
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top