我进行了一些谷歌搜索,发现了这个链接的内容:
函数调用 call_gmon_start 初始化 gmon 分析系统。
当二进制文件使用 -pg 标志编译时会启用该系统,并创建供 gprof(1) 使用的输出。
在场景二进制文件中,call_gmon_start 位于 _start 函数直接之前。
call_gmon_start 函数查找全局偏移表(也称为 __gmon_start__)中的最后一个条目,
如果不为 NULL,则将控制权传递给指定地址。__gmon_start__ 元素指向 gmon 初始化函数,
该函数开始记录分析信息并在 atexit() 中注册清理函数。但是,在我们的情况下并未使用 gmon,
因此 __gmon_start__ 为 NULL。
所以...
- 是的,它与 gprof 有关。
- 我不确定为什么会留下这个符号。也许只是为了在编译为 gprof 时使用的占位符?
更新:
好的,我使用 -pg
和没有使用 -pg
编译了您的代码。
看起来 __gmon_start__
被映射到编译程序内的地址。
因此,我认为没有库会解析该符号,而是程序本身。
使用 -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
__gmon_start__代码的objdump:
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
在编译的 hello
程序中加入 __gmon_start__
后,你可以看到调用了 __monstartup
。(monstartup man page)
没有使用 -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
您可以在这里看到,__gmon_start__
符号的值被设置为 00000000
。
gmon_start
的偏移量是如何映射到物理地址的? - RouteMapper