关于链接器的库装载过程

学习了动态链接的过程之后,想深入学习一下,奈何实现过程过于复杂,实在没有能力去理解代码,就了解一下其调用过程吧,以64位程序动态链接为例子。

_start -> _dl_start,这两步主要是链接器的自举,跳过中间几步的关于数据收集的一些函数就到了
dl_main这个函数,可以看出实现基本尚在rtld.c这个文件,但最开始start的函数是在dl-machine.h定义的,可以自行观看。

pwndbg> info b
Num Type Disp Enb Address What
6 breakpoint keep y 0x00007ffff7fe44e0 in elf_machine_rela at ../sysdeps/x86_64/dl-machine.h:323
7 breakpoint keep y 0x00007ffff7fe4030 in _dl_start at ./elf/rtld.c:527
8 breakpoint keep y 0x00007ffff7fe4517 in _dl_start at ./elf/rtld.c:588
9 breakpoint keep y 0x00007ffff7fe48e0 in dl_main at ./elf/rtld.c:1320
10 breakpoint keep y <MULTIPLE>
breakpoint already hit 1 time
10.1 y 0x0000555555555060 <_start>
10.2 y 0x00007ffff7fe3290 <_start>

dlmain

可以看出dlmain是完成装载的核心函数。因此想要分析链接器的实现可以从上述调用链入手。但是慎入吧。

关于main执行前的一些步骤以及程序退出处理

除了链接器中有__start函数,动态链接库中也有,会在main开始之前完成一些列复杂操作,但是在此之前发现了个好玩的东西,也就是在__start函数执行前,动态链接器还会执行_dl_init等函数,好像是库依赖关系之间的处理,不知道是干什么的。

执行链,不知道是不是因为程序不是c++,所以没有调用csu,c++的估计才是完全版
_start->__libc_start_main->__cxa_atexit(貌似是析构函数的注册表)->init(进行main前的准备)->frame_dummy(这玩意困惑了好长时间一直不知道干什么有机会深入研究吧)-> _dl_audit_preinit(又是一个奇怪的东西)->__libc_start_call_main(还好没有跳过,这个函数里面会调用main函数...)->main->exit->__run_exit_handlers->__call_tls_dtors->_dl_fini(看样子进入和退出都会经过连接器啊)->_IO_cleanup(刷新IO)->_exit(最后的最后调用系统调用kill掉pro)