2012-10-02 13 views
11

Mam kompilacji tego kodu z gcc hello.c -o cześć -O3Co to jest symbol __gmon_start__?

#include <stdio.h> 

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

kiedy notować delokalizacji uzyskać:

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

kiedy listy symboli w tym pliku otrzymuję :

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

Czy gmon_start ma coś todo z gprof? Dlaczego przesuwa się ten symbol, nawet gdy nie kompilowałem/łączałem z -pg lub -g? Jaka biblioteka rozwiązałaby ten symbol?

Odpowiedz

10

Czy trochę googling i znaleźć ten z here:

Funkcja call_gmon_start inicjuje system gmon profilowania. Ten system jest włączony, gdy pliki binarne są kompilowane z flagą -pg, i tworzy dane wyjściowe do użycia z gprof (1). W przypadku scenariusza funkcja binarna call_gmon_start znajduje się bezpośrednio po uruchomieniu funkcji _start . Funkcja call_gmon_start znajduje ostatni wpis w tabeli globalnych odsunięć (jeśli jest to NULL), przekazuje kontrolę do podanego adresu. Element __gmon_start__ wskazuje na funkcję inicjowania gmon, która rozpoczyna rejestrowanie informacji o profilowaniu i rejestruje funkcję czyszczenia przy pomocy atexit ( ). W naszym przypadku jednak gmon nie jest używany i jako taki __gmon_start__ ma wartość NULL.

Więc ...

  1. Tak, to ma coś wspólnego z gprof
  2. Nie jestem pewien, dlaczego symbolem jest uzyskiwanie lewo tam. Może tylko uchwyt na miejsce, gdy jest skompilowany dla gprof?

Aktualizacja:

Ok, więc skompilowany kod i bez -pg. Wygląda na to, że __gmon_start__ jest mapowany na adres w skompilowanym programie. Mówiąc to, nie sądzę, że istnieje biblioteka, która rozwiązuje ten symbol, ale sam program.

z -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 z __gmon_start__ kodu:

[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 

Z __gmon_start__ obecnej w skompilowanej hello programu, można zobaczyć, że __monstartup nazywa się.(monstartup man page)

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

Widać tutaj, że wartość symbolu __gmon_start__ jest ustawiony na 00000000.

+0

o około trzecim pytaniu? Czy powinienem wziąć pod uwagę ostatni wpis w GOT jako adres __gon_start__? Ponadto, sprawdzając plik binarny "hello" okazuje się, że istnieje wpis: __gmon_start __ @ plt i inny (wpis PLT) __gmon_start __ @ plt-0x10> – JohnTortugo

+0

W jaki sposób przesunięcie dla 'gmon_start' jest mapowane na adres fizyczny ? – RouteMapper