nm muestra los valores de los símbolos. Algunos símbolos en una biblioteca o archivo de objeto pueden mostrarse como cero simplemente porque aún no se les ha dado un valor. Obtendrán su valor real en el momento del enlace.
Algunos símbolos son símbolos de código, otros son datos, etc. Antes de vincular, el valor del símbolo suele ser el desplazamiento en la sección en la que reside,
El número hexadecimal es el desplazamiento de memoria en los archivos de objetos donde se puede encontrar el símbolo. Es literalmente el número de bytes en el código objeto.
El enlazador usa ese valor para ubicar y hacer una copia del valor del símbolo. Puede ver en general cómo se presenta si agrega el -S
opción a nm
, que le mostrará el tamaño del valor de cada símbolo.
Aquí hay un fragmento de código que escribí en C:
#include
#include
void foo();
int main(int argc, char* argv[]) {
foo();
}
void foo() {
printf("Foo bar baz!");
}
Ejecuté gcc -c foo.c
en ese código. Esto es lo que nm foo.o
mostró:
000000000000001b T foo 0000000000000000 T main U printf
Para este ejemplo, estoy ejecutando Ubuntu Linux de 64 bits; es por eso que el hexadecimal de 8 dígitos que ves aquí es de 16 dígitos. :-)
El dígito hexadecimal que ve es la dirección del código en cuestión dentro del archivo de objeto relativo al comienzo del .text.
sección. (suponiendo que abordamos secciones del archivo de objeto que comienzan en 0x0). Si ejecuta objdump -td foo.o
, verá lo siguiente en la salida:
Disassembly of section .text: 0000000000000000 : 0: 55 push %rbp 1: 48 89 e5 mov %rsp,%rbp 4: 48 83 ec 10 sub $0x10,%rsp 8: 89 7d fc mov %edi,-0x4(%rbp) b: 48 89 75 f0 mov %rsi,-0x10(%rbp) f: b8 00 00 00 00 mov $0x0,%eax 14: e8 00 00 00 00 callq 19 19: c9 leaveq 1a: c3 retq 000000000000001b : 1b: 55 push %rbp 1c: 48 89 e5 mov %rsp,%rbp 1f: b8 00 00 00 00 mov $0x0,%eax 24: 48 89 c7 mov %rax,%rdi 27: b8 00 00 00 00 mov $0x0,%eax 2c: e8 00 00 00 00 callq 31 31: c9 leaveq 32: c3 retq
Observe que estos dos símbolos se alinean con las entradas que vimos en la tabla de símbolos de nm
. Tenga en cuenta que estas direcciones pueden cambiar si vincula este archivo de objeto a otros archivos de objeto. Además, ten en cuenta que callq
at 0x2c cambiará cuando vincule este archivo a cualquier libc que proporcione su sistema, ya que actualmente es una llamada incompleta a printf (no sabe dónde está ahora).
En cuanto a tu mylib.a
, hay más pasando aquí. El archivo que tienes es un archivo; contiene múltiples archivos objeto, cada uno de los cuales con su propio segmento de texto. Como ejemplo, aquí hay parte de un nm contra /usr/lib/libm.a en mi casilla aquí
e_sinh.o: 0000000000000000 r .LC0 0000000000000008 r .LC1 0000000000000010 r .LC2 0000000000000018 r .LC3 0000000000000000 r .LC4 U __expm1 U __ieee754_exp 0000000000000000 T __ieee754_sinh e_sqrt.o: 0000000000000000 T __ieee754_sqrt e_gamma_r.o: 0000000000000000 r .LC0 U __ieee754_exp 0000000000000000 T __ieee754_gamma_r U __ieee754_lgamma_r U __rint
Verá que varias entradas de segmentos de texto, indicadas por la T en la segunda columna, descansan en la dirección 0x0, pero cada archivo individual tiene solo un símbolo de segmento de texto en 0x0.
En cuanto a los archivos individuales que tienen varios símbolos en la misma dirección, parece que sería ser posible tal vez. Después de todo, es solo una entrada en una tabla que se usa para determinar la ubicación y el tamaño de una porción de datos. Pero no lo sé con certeza. Nunca antes había visto varios símbolos que hicieran referencia a la misma parte de una sección. Cualquiera con más conocimientos sobre esto que yo puede intervenir. :-)
Espero que esto ayude un poco.