gpt4 book ai didi

c - "__gmon_start__"符号是什么?

转载 作者:IT王子 更新时间:2023-10-29 00:20:46 24 4
gpt4 key购买 nike

我正在使用 gcc hello.c -o hello -O3 编译这段代码:

#include <stdio.h>

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

当我列出我得到的搬迁时:

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__

当我在这个文件中列出符号时,我得到:

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__

gmon_start 与 gprof 有什么关系吗?为什么即使我没有使用 -pg-g 编译/链接它也会重定位该符号?哪个库可以解析这个符号?

最佳答案

在谷歌上搜索了一下,从 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.

所以...

  1. 是的,它确实与gprof有关
  2. 我不确定为什么符号会留在那儿。也许只是为 gprof 编译时的占位符?

更新:

好的,所以我在使用和不使用 -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

关于c - "__gmon_start__"符号是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12697081/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com