¿Cómo enumero los símbolos que se exportan desde un archivo .so? Si es posible, también me gustaría saber su fuente (por ejemplo, si se extraen de una biblioteca estática).
Estoy usando gcc 4.0.2, si eso hace la diferencia.
nm
, no GNU nm
.
¿Cómo enumero los símbolos que se exportan desde un archivo .so? Si es posible, también me gustaría saber su fuente (por ejemplo, si se extraen de una biblioteca estática).
Estoy usando gcc 4.0.2, si eso hace la diferencia.
nm
, no GNU nm
.
Respuestas:
La herramienta estándar para enumerar símbolos es nm
, puede usarla simplemente así:
nm -gD 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 -gDC yourLib.so
Si su archivo .so está en formato elf, tiene dos opciones:
Cualquiera de los dos objdump
( -C
también es útil para exigir 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 use 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
le mostrará todos los símbolos y nm -g
muestra solo los símbolos visibles desde el exterior. Esto puede ser confuso si está examinando múltiples archivos de símbolos y comienza a intercambiar sus comandos.
objectdump -TC
a la lista. Por el contrario readelf -Ws
, no muestra los nombres destrozados.
.so
archivos que deba agregar --dynamic
a la nm
línea de comandos.
Si su .so
archivo está en formato elf, puede usar el programa readelf para extraer información de símbolos del binario. Este comando te dará la tabla de símbolos:
readelf -Ws /usr/lib/libexample.so
Solo debe extraer los definidos en este .so
archivo, no en las bibliotecas a las que hace referencia. La séptima columna debe contener un número en este caso. Puede extraerlo usando una expresión regular simple:
readelf -Ws /usr/lib/libstdc++.so.6 | grep '^\([[:space:]]\+[^[:space:]]\+\)\{6\}[[:space:]]\+[[:digit:]]\+'
o, tal como se propone por Caspin ,:
readelf -Ws /usr/lib/libstdc++.so.6 | awk '{print $8}';
objdump -TC /usr/lib/libexample.so
Me preguntaba por qué -fvisibility = hidden y la visibilidad #pragma GCC no parecía tener ninguna influencia, ya que todos los símbolos siempre eran visibles con nm , hasta que encontré esta publicación que me señalaba readelf y objdump , lo que me hizo darme cuenta de que allí parecen ser en realidad dos tablas de símbolos:
Creo que el primero contiene símbolos de depuración que pueden eliminarse con strip o el modificador -s que puede asignar al vinculador o al comando de instalación . E incluso si nm ya no enumera nada, sus símbolos exportados todavía se exportan porque están en la "tabla de símbolos dinámicos" ELF, que es la última.
Para .so
archivos C ++ , el nm
comando final esnm --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)
Intente agregar -l a las banderas nm para obtener la fuente de cada símbolo. Si la biblioteca se compila 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 de objetos / biblioteca estática es probablemente desconocido 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
.
Puede usar la 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 se pueda recuperar. Quizás objcopy
revela más información.
/ EDITAR: el nombre de la herramienta es, por supuesto nm
. La bandera -g
se usa para mostrar solo los símbolos exportados.
nm -g enumera la variable externa, que no es necesariamente un símbolo exportado. Cualquier variable de alcance de archivo no estático (en C) son todas variables externas.
nm -D mostrará el símbolo en la tabla dinámica, que puede encontrar su dirección por dlsym.
nm --version
GNU nm 2.17.50.0.6-12.el5 20061020
Si solo quiere saber si hay símbolos presentes , puede usar
objdump -h /path/to/object
o para enumerar la información de depuración
objdump -g /path/to/object
nm
no responde a algunas opciones, como-D
y-g
(IIRC).