2012-10-02 12 views
11

Ich Kompilieren Sie diesen Code mit gcc hello.c -o hallo O3Was ist das Symbol __gmon_start__?

#include <stdio.h> 

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

, wenn ich die Verlagerungen Liste erhalte ich:

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

, wenn ich die Symbole in dieser Datei auflisten ich :

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

Hat gmon_start irgendetwas mit gprof zu tun? Warum muss ich für dieses Symbol umziehen, obwohl ich nicht mit -pg oder -g kompiliert/verlinkt habe? Welche Bibliothek würde dieses Symbol auflösen?

Antwort

10

habe ein wenig googeln und fand diese von here:

Die Funktion call_gmon_start die GMON Profilierungssystem initialisiert. Dieses System wird aktiviert, wenn Binärdateien mit dem Flag -pg, , kompiliert werden und eine Ausgabe für die Verwendung mit gprof (1) erstellt wird. Im Fall des Szenarios wird die binäre Funktion call_gmon_start direkt nach der Funktion _start ausgeführt. Die Funktion call_gmon_start findet den letzten Eintrag in der globalen Offset-Tabelle (auch bekannt als __gmon_start__), und wenn nicht NULL, gibt die Steuerung an die angegebene Adresse weiter. Das Element __gmon_start__ verweist auf die Initialisierungsfunktion gmon, die die Aufzeichnung von Profilinformationen startet und eine Bereinigungsfunktion mit atexit() registriert. In unserem Fall wird gmon jedoch nicht verwendet und __gmon_start__ ist NULL.

So ...

  1. Ja, es etwas hat mit gprof
  2. Ich bin mir nicht sicher, warum das Symbol zu tun bleibt immer drin. Vielleicht nur ein Platzhalter für wenn es für gprof kompiliert ist?

Update:

Okay, so dass ich Ihren Code mit und ohne -pg zusammengestellt. Es sieht so aus, als ob __gmon_start__ auf eine Adresse innerhalb des kompilierten Programms abgebildet wird. Wenn ich das sage, denke ich nicht, dass es eine Bibliothek gibt, die dieses Symbol auflöst, sondern das Programm selbst.

mit -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 von __gmon_start__ Code:

[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 

Mit dem __gmon_start__ in dem kompilierten hello Programm können Sie sehen, dass die __monstartup ins Leben gerufen wird.(monstartup man page)

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

Sie hier sehen können, dass der Symbolwert von __gmon_start__-00000000 gesetzt.

+0

über die dritte Frage? Sollte ich den letzten Eintrag in GOT als die Adresse von __gmon_start__ betrachten? Auch bei der Überprüfung der Binärdatei von "Hallo" stellt sich heraus, dass es einen Eintrag gibt: __gmon_start __ @ plt und ein anderer (der PLT-Eintrag) __gmon_start __ @ pt-0x10> – JohnTortugo

+0

Wie also wird der Offset für 'gmon_start' auf eine physikalische Adresse abgebildet ? – RouteMapper