Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the "__gmon_start__" symbol?

Tags:

I'm compiling this code with gcc hello.c -o hello -O3:

#include <stdio.h>  int main(void) {     printf("Hello world\n");     return 0; } 

and when I list the relocations I get:

test@southpark$ readelf -r hello | grep gmon 080495a4  00000106 R_386_GLOB_DAT    00000000   __gmon_start__ 080495b4  00000107 R_386_JUMP_SLOT   00000000   __gmon_start__ 

When I list the symbols in this file I get:

test@southpark$ readelf -s hello | grep gmon      1: 00000000     0 NOTYPE  WEAK   DEFAULT  UND __gmon_start__     48: 00000000     0 NOTYPE  WEAK   DEFAULT  UND __gmon_start__ 

Does gmon_start have anything to do with gprof? Why does it have a relocation for that symbol even I didn't compile/link with -pg or -g? What library would resolve this symbol?

like image 377
JohnTortugo Avatar asked Oct 02 '12 19:10

JohnTortugo


1 Answers

Did a little googling and found this from here:

The function call_gmon_start initializes the gmon profiling system. This system is enabled when binaries are compiled with the -pg flag, and creates output for use with gprof(1). In the case of the scenario binary call_gmon_start is situated directly proceeding that _start function. The call_gmon_start function finds the last entry in the Global Offset Table (also known as __gmon_start__) and, if not NULL, will pass control to the specified address. The __gmon_start__ element points to the gmon initialization function, which starts the recording of profiling information and registers a cleanup function with atexit(). In our case however gmon is not in use, and as such __gmon_start__ is NULL.

So...

  1. Yes, it does have something to do with gprof
  2. I'm not sure why the symbol is getting left in there. Maybe just a place holder for when it's compiled for gprof?

Update:

Okay, so I compiled your code with and without -pg. It looks like __gmon_start__ gets mapped to an address within the compiled program. So with that being said, I don't think there's a library which resolves that symbol, but the program itself.

with -pg:

akyserr@orion:~$ 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 of __gmon_start__ code:

akyserr@orion:~$ 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 <__monstartup@plt>  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 

With the __gmon_start__ present in the compiled hello program, you can see that that __monstartup is called into. (monstartup man page)

without -pg:

akyserr@orion:~$ 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 

You can see here, that the symbol value of __gmon_start__ is set to 00000000.

like image 178
rkyser Avatar answered Oct 06 '22 13:10

rkyser