当将c(或asm)中的类似hello-world的程序与gcc
链接时,它会在结果可执行对象文件中添加一些内容。我只知道运行时动态链接器和_start
入口点,但这些添加的函数是什么类型的?
00000000004003f0 t deregister_tm_clones
0000000000400430 t register_tm_clones
0000000000400470 t __do_global_dtors_aux
0000000000400490 t frame_dummy
00000000004004e0 T __libc_csu_init
0000000000400550 T __libc_csu_fini
0000000000400554 T _fini
0000000000600668 t __frame_dummy_init_array_entry
0000000000600668 t __init_array_start
0000000000600670 t __do_global_dtors_aux_fini_array_entry
0000000000600670 t __init_array_end
他们是什么,为了什么?是在某处描述的吗?谷歌搜索没有帮助。
其中大多数是在“主”程序本身之前或之后执行代码的各种方法,大多数都存在于crtstuff.c
(https://github.com/gcc-mirror/gcc/blob/master/libgcc/crtstuff.c)中。它们的存在是为了支持各种类C语言编程语言的功能,但它们也可以在C中访问。它似乎过于复杂,因为其中一些代表了传统的包袱和一些支持GCC运行的各种不同架构所需的变化。
从您的列表中逐个(或两个两个):
00000000004003f0 t deregister_tm_clones
0000000000400430 t register_tm_clones
事务性内存旨在使线程编程更简单。它是基于锁的同步的替代方案。这些例程分别拆除和设置由支持这些功能的库(libitm)使用的表。有关TM的更多信息,请访问https://gcc.gnu.org/wiki/TransactionalMemory和http://pmarlier.free.fr/gcc-tm-tut.html
0000000000400470 t __do_global_dtors_aux
在.fini_array
不可用的系统上退出程序时运行所有全局析构函数。
0000000000400490 t frame_dummy
此功能位于.init
部分。它被定义为void frame_dummy ( void )
,它的生命中的全部意义是调用具有参数的__register_frame_info_bases
。显然,使用来自.init
部分的参数调用函数可能是不可靠的,因此这个函数所以__register_frame_info_bases
不会直接从.init section
调用。 .eh_frame
信息库用于异常处理和类似功能(例如用__attribute__((cleanup(..)))
声明的函数)。
00000000004004e0 T __libc_csu_init
0000000000400550 T __libc_csu_fini
它们运行任何程序级初始化程序和终结程序(类似于整个程序的构造函数/析构函数)。如果您定义如下函数:
void __attribute__ ((constructor)) mefirst () {
/* ... do something here ... */
}
void __attribute__ ((destructor)) melast () {
/* ... do something here ... */
}
它们将分别通过这些例程在main()
之前和之后调用。另见https://gcc.gnu.org/onlinedocs/gccint/Initialization.html
0000000000400554 T _fini
这是一种现在不推荐使用的方式来运行程序级(实际上是对象文件级)析构函数(有关这方面的一些信息可以在man dlclose
中找到)。构造函数的相应过时函数是__init
。
0000000000600668 t __frame_dummy_init_array_entry
0000000000600668 t __init_array_start
这些标记.init_array
部分的结束和开始,其中包含指向所有程序级初始值设定项的指针(请参阅上面的__libc_csu_init)。
0000000000600670 t __do_global_dtors_aux_fini_array_entry
0000000000600670 t __init_array_end
这些标记.fini_array
部分的结束和开始,其中包含指向所有程序级终结器的指针(请参阅上面的__libc_csu_fini)。
[编辑]一些附加说明: