为什么从glibc的的CSU / INIT-first.c _init调用之前_start即使_start是ELF切入点? [英] Why is _init from glibc's csu/init-first.c called before _start even if _start is the ELF entry point?

查看:326
本文介绍了为什么从glibc的的CSU / INIT-first.c _init调用之前_start即使_start是ELF切入点?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我第一次注意到它,而与广发行的 rbreak玩,然后做了一个小例子:

I first noticed it while playing with GDB's rbreak ., and then made a minimal example:

(gdb) file hello_world.out
Reading symbols from hello_world.out...done.
(gdb) b _init
Breakpoint 1 at 0x4003e0
(gdb) b _start
Breakpoint 2 at 0x400440
(gdb) run
Starting program: /home/ciro/bak/git/cpp/cheat/gdb/hello_world.out

Breakpoint 1, _init (argc=1, argv=0x7fffffffd698, envp=0x7fffffffd6a8) at ../csu/init-first.c:52
52  ../csu/init-first.c: No such file or directory.
(gdb) continue
Continuing.

Breakpoint 2, 0x0000000000400440 in _start ()
(gdb) continue
Continuing.

Breakpoint 1, 0x00000000004003e0 in _init ()
(gdb) info breakpoints
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   <MULTIPLE>
    breakpoint already hit 2 times
1.1                         y     0x00000000004003e0 <_init>
1.2                         y     0x00007ffff7a36c20 in _init at ../csu/init-first.c:52
2       breakpoint     keep y   0x0000000000400440 <_start>
    breakpoint already hit 1 time

请注意,有2 _init :一个在 CSU / INIT-first.c ,和对方似乎来自 sysdeps / x86_64的/ crti.S 。我说的是在 CSU 之一。

Note that there are 2 _init: one in csu/init-first.c, and the other seems to come from sysdeps/x86_64/crti.S. I'm talking about the csu one.

_start 应该是入口点链接器设置,并存储在ELF头?是什么机制使 _init 先运行?其目的是什么?

Isn't _start supposed to be the entry point set by the linker, and stored in the ELF header? What mechanism makes _init run first? What is its purpose?

,glibc的2.19,GDB 7.7.1和Ubuntu 14.04。

Tested on GCC 4.8, glibc 2.19, GDB 7.7.1 and Ubuntu 14.04.

推荐答案

当第一次调试暂停在你的例子不是过程的真正开始。

Where the debugger halts first in your example isn't the real beginning of the process.

在ELF头没有为计划间的preTER(动态链接器)的条目。在Linux上的64位其值 /lib64/ld-linux-x86-64.so.2 。内核初始指令指针设置为这个计划间preTER 的切入点。它的符号名是 _start 太像节目 _start

In the ELF header there is an entry for the program interpreter (dynamic linker). On Linux 64 bit its value is /lib64/ld-linux-x86-64.so.2. The kernel sets the initial instruction pointer to the entry point of this program interpreter. The symbol name of it is _start too, like the programs _start.

动态链接程序已经完成了它的工作后,调用也是在程序的功能,如 _init glibc中,它调用程序的入口点。

After the dynamic linker has done its work, calling also functions in the program, like _init in glibc, it calls the entry point of the program.

_start 断点不会为动态链接器工作,因为它只需程序的 _start 。

The breakpoint at _start doesn't work for the dynamic linker because it takes only the address of the program's _start.

您可以找到切入点地址 readelf -h /lib64/ld-linux-x86-64.so.2

You can find the entry point address with readelf -h /lib64/ld-linux-x86-64.so.2.

您也可以设置一个断点 _dl_start 并打印回溯一看就知道这个功能是从动态链接程序的 _start

You could also set a breakpoint at _dl_start and print a backtrace to see that this function is called from dynamic linker's _start.

如果你下载的glibc的电流源$ C ​​$ C你可以在找动态加载程序的入口点的glibc-2.21 / sysdeps / x86_64的/ DL-machine.h 在出发线121。

If you download glibc's current source code you can find the entry point of the dynamic loader at glibc-2.21/sysdeps/x86_64/dl-machine.h starting on line 121.

这篇关于为什么从glibc的的CSU / INIT-first.c _init调用之前_start即使_start是ELF切入点?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆