2009-12-07 11 views
13

Quando si elenca la tabella dei simboli di una libreria statica, ad esempio nm mylib.a, cosa significa l'esagono di 8 cifre visualizzato accanto a ciascun simbolo? È la posizione relativa di ciascun simbolo nel codice?Cosa significa "valore simbolo" dal comando nm?

Inoltre, i simboli multipli possono avere lo stesso valore di simbolo? C'è qualcosa di sbagliato in un gruppo di simboli diversi che hanno tutti il ​​valore del simbolo di 00000000?

risposta

21

Ecco un frammento 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 cosa nm foo.o mostrato:

 
000000000000001b T foo 
0000000000000000 T main 
       U printf 

Per questo esempio sto facendo funzionare Ubuntu Linux a 64-bit; ecco perché l'esagono di 8 cifre che vedi è di 16 cifre qui. :-)

La cifra esadecimale che vedi è l'indirizzo del codice in questione all'interno del file oggetto relativo all'inizio della sezione . (supponendo che indirizziamo le sezioni del file oggetto a partire da 0x0). Se si esegue objdump -td foo.o, si vedrà il seguente 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 

Si noti che questi due simboli giusta linea con le voci che abbiamo visto nella tabella dei simboli da nm. Bare a mente, questi indirizzi possono cambiare se si collega questo file oggetto ad altri file oggetto. Inoltre, tieni a mente che callq a 0x2c cambierà quando colleghi questo file a qualsiasi libc fornita dal tuo sistema, dal momento che al momento è una chiamata incompleta a printf (non sa dove sia in questo momento).

Per quanto riguarda il tuo mylib.a, c'è di più in corso qui. Il file che hai è un archivio; contiene più file oggetto, ognuno dei quali con il proprio segmento di testo. A titolo di esempio, qui è 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 

Vedrete che più entires segmento di testo - indicato dalla T nella seconda colonna di riposo all'indirizzo 0x0, ma ogni singolo file ha solo un simbolo di segmento di testo a 0x0.

Come per i singoli file con più simboli che riposano allo stesso indirizzo, sembra che sia possibile.Dopo tutto, è solo una voce in una tabella utilizzata per determinare la posizione e le dimensioni di un blocco di dati. Ma non lo so per certo. Non ho mai visto più simboli che facciano riferimento alla stessa parte di una sezione prima. Chiunque abbia più conoscenze su di me di me può intervenire. :-)

Spero che questo aiuti alcuni.

+0

Se si compila il proprio esempio con 'x86_64-w64-mingw32-g ++', si vedrà con 'nm' un simbolo multiplo che fa riferimento all'indirizzo zero e ha il segno' A', cioè l'indirizzo non essere cambiato in futuro. Per esempio. '0000000000000000 A __dll__ 0000000000000000 A __dll_characteristics__'. Giusto al punto - [Ho visto che c'erano] (http://unix.stackexchange.com/q/158162/59928) mappato effettivamente funzioni utili. Mi chiedo, cosa poteva significare? –

3

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 è strutturato se aggiungi l'opzione -S a nm, che ti mostrerà la dimensione del valore per ciascun simbolo.

0

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 reale al momento del collegamento.

Alcuni simboli sono simboli di codice, alcuni sono dati, ecc Prima che collega il valore del simbolo è spesso l'offset nella sezione risiede in,

Problemi correlati