2012-10-02 21 views
11

Estoy compilando el código con gcc hello.c -o hola -O3¿Qué es el símbolo __gmon_start__?

#include <stdio.h> 

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

cuando enumero las reubicaciones me sale:

[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__ 

cuando enumero los símbolos en este archivo me sale :

[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__ 

¿Tiene gmon_start algo que hacer con gprof? ¿Por qué tiene una reubicación para ese símbolo incluso si no compilé/vinculé con -pg o -g? ¿Qué biblioteca resolvería este símbolo?

Respuesta

10

hice un poco de google y encontró esto desde here:

El call_gmon_start función inicializa el sistema gmon perfiles. Este sistema se habilita cuando los binarios se compilan con el indicador -pg, y crea salida para usar con gprof (1). En el caso del escenario , el binario call_gmon_start se encuentra directamente procediendo a esa función _start . La función call_gmon_start encuentra la última entrada en el Global Offset Table (también conocida como __gmon_start__) y, si no es NULL, pasará el control a la dirección especificada. El elemento __gmon_start__ apunta a la función de inicialización de gmon, que inicia la grabación de información de perfil y registra una función de limpieza con atexit(). En nuestro caso, sin embargo, gmon no está en uso, y como tal __gmon_start__ es NULL.

Entonces ...

  1. Sí, sí que tiene algo que ver con gprof
  2. No estoy seguro de por qué el símbolo se están quedando allí. ¿Tal vez solo un marcador de posición para cuando se compila para gprof?

Actualización:

bien, así que el código compilado con y sin -pg. Parece que __gmon_start__ se asigna a una dirección dentro del programa compilado. Entonces dicho esto, no creo que haya una biblioteca que resuelva ese símbolo, sino el programa en sí.

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 de __gmon_start__ código:

[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 en el programa compilado hello, se puede ver que esa __monstartup se pone en.(monstartup man page)

sin -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 

Se puede ver aquí, que el valor de símbolo de __gmon_start__ se establece en 00000000.

+0

acerca de la tercera pregunta? ¿Debo considerar la última entrada en GOT como la dirección de __gmon_start__? Además, al inspeccionar el binario de "hello" resulta que hay una entrada: __gmon_start __ @ plt y otra (la entrada PLT) __gmon_start __ @ plt-0x10> – JohnTortugo

+0

Entonces, ¿cómo se asigna el desplazamiento de 'gmon_start' a una dirección física ? – RouteMapper

Cuestiones relacionadas