nm mostra i valori dei simboli. Alcuni simboli in una libreria o in un file oggetto possono apparire come zero semplicemente perché non hanno ancora ricevuto un valore. Otterranno il loro valore effettivo al momento del collegamento.
Alcuni simboli sono simboli di codice, altri sono dati, ecc. Prima del collegamento, il valore del simbolo è spesso l'offset nella sezione in cui risiede,
Il numero esadecimale è l'offset di memoria nei file oggetto in cui è possibile trovare il simbolo. È letteralmente il numero di byte nel codice oggetto.
Tale valore viene utilizzato dal linker per individuare e creare una copia del valore del simbolo. Puoi vedere in generale come è disposto se aggiungi -S
opzione a nm
, che ti mostrerà la dimensione del valore per ciascun simbolo.
Ecco uno snippet di codice che ho scritto in C:
#include
#include
void foo();
int main(int argc, char* argv[]) {
foo();
}
void foo() {
printf("Foo bar baz!");
}
Ho eseguito gcc -c foo.c
su quel codice Ecco cos'è nm foo.o
mostrato:
000000000000001b T foo 0000000000000000 T main U printf
Per questo esempio eseguo Ubuntu Linux a 64 bit; ecco perché l'esadecimale a 8 cifre che vedi qui è di 16 cifre. :-)
La cifra esadecimale che vedi è l'indirizzo del codice in questione all'interno del file oggetto relativo all'inizio del .text.
sezione. (supponendo che indirizziamo sezioni del file oggetto che iniziano a 0x0). Se esegui objdump -td foo.o
, vedrai quanto segue nell'output:
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
Nota che questi due simboli si allineano con le voci che abbiamo visto nella tabella dei simboli da nm
. Tieni presente che questi indirizzi potrebbero cambiare se colleghi questo file oggetto ad altri file oggetto. Inoltre, tieni presente che callq
at 0x2c cambierà quando colleghi questo file a qualunque libc fornita dal tuo sistema, dato che attualmente è una chiamata incompleta a printf (non sa dove si trova in questo momento).
Per quanto riguarda il tuo mylib.a
, qui c'è dell'altro. Il file che hai è un archivio; contiene multipli file oggetto, ognuno dei quali con il proprio segmento di testo. Ad esempio, ecco parte di un nm contro /usr/lib/libm.a sulla mia casella qui
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
Vedrai che più voci di segmenti di testo, indicate dalla T nella seconda colonna, si trovano all'indirizzo 0x0, ma ogni singolo file ha solo un simbolo di segmento di testo a 0x0.
Per quanto riguarda i singoli file con più simboli che si trovano allo stesso indirizzo, sembra che farebbe essere possibile forse. Dopotutto, è solo una voce in una tabella utilizzata per determinare la posizione e la dimensione di un blocco di dati. Ma non lo so per certo. Non ho mai visto più simboli che fanno riferimento alla stessa parte di una sezione prima. Chiunque sia più esperto di me può intervenire. :-)
Spero che questo aiuti un po'.