crt:c run time 的缩写
用于初始化进入main之前的工作 ,全局构造和析构 以及 退出 main函数 后的清理工作
程序链接时编译器会给程序自动加上一下五个的某几个目标文件:
crt1.o, crti.o, crt begin.o, crt end.o, crtn.o
daemon.o 由我们自己的C程序文件产生
可执行文件 = 某几个/全部(crt1.o, crti.o, crtbegin.o, crtend.o, crtn.o ) + daemon.o
在标准的linux平台下,链接的顺序是: ld crt1.o crti.o [user_objects] [system_libraries] crtn.o
crt1.o:起初也叫crt.o,包含了主函数的入口地址 _start 等,ctr.o == crt1.o
说白了就是调用main函数
由它负责调用__libc_start_main初始化libc 并且 调用main函数进入真正的程序主体。
有些链接器对链接时目标文件和库的顺序有依赖性,
crt.o这个文件必须被放在链接器命令行中的所有输入文件中的第一个
crtbegin.o
crtend.o
# 真正C++全局构造和析构是由crtbegin.o和crtend.o实现的
crtbegin.o和crtend.o是C++语言的启动模块,由编译器gcc提供;
而crt1.o则与crt0.o的作用类似,主要用于在调用main()之前做一些初始化工作,全局符号_start就定义在这个模块中。
crtbegin.o和crtend.o主要用于C++语言,在.ctors和.dtors区中执行全局构造(constructor)和析构(destructor)函数。
crti.o: init()函数的代码 .init在main函数前运行
crtn.o :fini()函数的代码 .finit在main函数后运行
# crti.o和crtn.o只是提供了main之前和之后执行代码的机制
init段,.finit 段需要的一些辅助代码,分别位于crti.o和crtn.o。
开始是来自crti.o的,而末尾是来自crtn.o的,中间才是真正程序的全局构造或者析构函数,
也就是说程序的全局构造和析构仅仅是_init和_finit的中间部分.
_start 函数调用: __libc_start_main 函数
__libc_start_main 会调用 __libc_csu_init, __libc_csu_fini,及main 函数
简单表示为如下:
__libc_start_main (main,__libc_csu_init,__libc_csu_fini)
__libc_csu_init, 负责调用_init()
__libc_csu_fini, 负责调用_finit()
crtbegin.o crtend.o文件:
这两个文件是用于配合glibc实现C++全局构造和析构的。
构造过程:
_start-->__lib_start_main-->__libc_csu_init-->_init--> __do_global_ctors