2012-10-02 9 views
11

Sto compilando questo codice con gcc hello.c -o ciao -O3Che cos'è il simbolo __gmon_start__?

#include <stdio.h> 

int main(void) { 
    printf("Hello world\n"); 
    return 0; 
} 

quando vi elenco le delocalizzazioni ottengo:

[email protected]$ readelf -r hello | grep gmon 
080495a4 00000106 R_386_GLOB_DAT 00000000 __gmon_start__ 
080495b4 00000107 R_386_JUMP_SLOT 00000000 __gmon_start__ 

quando vi elenco i simboli in questo file ottengo :

[email protected]$ readelf -s hello | grep gmon 
    1: 00000000  0 NOTYPE WEAK DEFAULT UND __gmon_start__ 
    48: 00000000  0 NOTYPE WEAK DEFAULT UND __gmon_start__ 

gmon_start ha qualcosa da fare con gprof? Perché ha un trasferimento per quel simbolo anche se non ho compilato/linkato con -pg o -g? Quale libreria risolverebbe questo simbolo?

risposta

10

fatto un po 'googling e abbiamo trovato questo da here:

La call_gmon_start funzione inizializza il sistema gmon profiling. Questo sistema è abilitato quando i binari sono compilati con il flag -pg, e crea l'output per l'uso con gprof (1). Nel caso dello scenario binary call_gmon_start si trova direttamente procedendo con la funzione _start . La funzione call_gmon_start trova l'ultima voce nella tabella di offset globale (nota anche come __gmon_start__) e, se non NULL, passerà il controllo all'indirizzo specificato. L'elemento __gmon_start__ punta alla funzione di inizializzazione di gmon, che avvia la registrazione delle informazioni di profilazione e registra una funzione di pulizia con atexit(). Nel nostro caso comunque gmon non è in uso, e come tale __gmon_start__ è NULL.

Quindi ...

  1. Sì, ha qualcosa a che fare con gprof
  2. Non sono sicuro che il motivo per cui il simbolo è sempre lasciato in là. Forse solo un segnaposto per quando è compilato per gprof?

Aggiornamento:

Va bene, così ho compilato il codice con e senza -pg. Sembra che __gmon_start__ venga mappato a un indirizzo all'interno del programma compilato. Quindi, detto questo, non penso che ci sia una libreria che risolve quel simbolo, ma il programma stesso.

con -pg:

[email protected]:~$ readelf -r hello 

Relocation section '.rel.dyn' at offset 0x32c contains 1 entries: 
Offset  Info Type   Sym.Value Sym. Name 
08049fec 00000806 R_386_GLOB_DAT 08048460 __gmon_start__ 

Relocation section '.rel.plt' at offset 0x334 contains 6 entries: 
Offset  Info Type   Sym.Value Sym. Name 
0804a000 00000607 R_386_JUMP_SLOT 080483b0 _mcleanup 
0804a004 00000107 R_386_JUMP_SLOT 00000000 __monstartup 
0804a008 00000207 R_386_JUMP_SLOT 00000000 mcount 
0804a00c 00000307 R_386_JUMP_SLOT 00000000 __cxa_atexit 
0804a010 00000407 R_386_JUMP_SLOT 00000000 puts 
0804a014 00000507 R_386_JUMP_SLOT 00000000 __libc_start_main 

objdump di __gmon_start__ Codice:

[email protected]:~$ objdump -S hello | grep "460 <__gmon_start__>:" -A 20 

08048460 <__gmon_start__>: 
8048460:  83 ec 1c    sub $0x1c,%esp 
8048463:  a1 20 a0 04 08   mov 0x804a020,%eax 
8048468:  85 c0     test %eax,%eax 
804846a:  75 2a     jne 8048496 <__gmon_start__+0x36> 
804846c:  c7 05 20 a0 04 08 01 movl $0x1,0x804a020 
8048473:  00 00 00 
8048476:  c7 44 24 04 36 86 04 movl $0x8048636,0x4(%esp) 
804847d:  08 
804847e:  c7 04 24 30 84 04 08 movl $0x8048430,(%esp) 
8048485:  e8 36 ff ff ff   call 80483c0 <[email protected]> 
804848a:  c7 04 24 b0 83 04 08 movl $0x80483b0,(%esp) 
8048491:  e8 1a 01 00 00   call 80485b0 <atexit> 
8048496:  83 c4 1c    add $0x1c,%esp 
8048499:  c3      ret  
804849a:  90      nop 
804849b:  90      nop 
804849c:  90      nop 
804849d:  90      nop 

Con la __gmon_start__ presente nel hello programma compilato, si può vedere che che __monstartup è chiamato in.(monstartup man page)

senza -pg:

[email protected]:~$ readelf -r hello 

Relocation section '.rel.dyn' at offset 0x290 contains 1 entries: 
Offset  Info Type   Sym.Value Sym. Name 
08049ff0 00000206 R_386_GLOB_DAT 00000000 __gmon_start__ 

Relocation section '.rel.plt' at offset 0x298 contains 3 entries: 
Offset  Info Type   Sym.Value Sym. Name 
0804a000 00000107 R_386_JUMP_SLOT 00000000 puts 
0804a004 00000207 R_386_JUMP_SLOT 00000000 __gmon_start__ 
0804a008 00000307 R_386_JUMP_SLOT 00000000 __libc_start_main 

Potete vedere qui, che il valore di simbolo __gmon_start__ è impostato su 00000000.

+0

sulla terza domanda? Dovrei considerare l'ultima voce in GOT come l'indirizzo di __gmon_start__? Inoltre, esaminando il file binario di "ciao" si scopre che c'è una voce: __gmon_start __ @ plt e un'altra (la voce PLT) __gmon_start __ @ plt-0x10> – JohnTortugo

+0

Quindi, come viene mappato l'offset per 'gmon_start' su un indirizzo fisico ? – RouteMapper

Problemi correlati