gcc给linux ELF增加了什么功能?
What functions does gcc add to the linux ELF?
当用 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-like 编程语言的特性,但也可以在 C 中访问它们。它可能看起来过于复杂,因为其中一些代表了遗留包袱,而一些变体需要支持 GCC 运行 所采用的各种不同架构。
从你的列表中,一个接一个(或两个接两个):
00000000004003f0 t deregister_tm_clones
0000000000400430 t register_tm_clones
事务内存旨在简化线程编程。
它是 lock-based 同步的替代方法。
这些例程分别拆除和设置支持这些功能的库 (libitm) 使用的 table。
有关 TM 的更多信息,请点击此处 https://gcc.gnu.org/wiki/TransactionalMemory and here 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
这些 运行 任何 program-level 初始化器和终结器(有点像整个程序的 constructors/destructors)。
如果您定义如下函数:
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
这是 now-deprecated 到 运行 一个 program-level (对象 file-level 实际上)析构函数的方法(有关此的一些信息可以在 man dlclose
).
构造函数对应的废弃函数是 __init
.
0000000000600668 t __frame_dummy_init_array_entry
0000000000600668 t __init_array_start
这些标记 .init_array
部分的结束和开始,其中包含指向所有 program-level 初始值设定项的指针(参见上面的 __libc_csu_init ).
0000000000600670 t __do_global_dtors_aux_fini_array_entry
0000000000600670 t __init_array_end
这些标记 .fini_array
部分的结束和开始,其中包含指向所有 program-level 终结器的指针(参见上面的 __libc_csu_fini ).
[编辑] 一些附加说明:
link
http://dbp-consulting.com/tutorials/debugging/linuxProgramStartup.html (wayback machine)
来自 Jester 的问题评论包含一个漂亮的图表和一个小样本
程序说明了这些东西的总体顺序 运行 以及如何
从 C 访问其中一些功能。
术语“ctors”和“dtors”是
分别为“构造函数”和“析构函数”。
全局constructors/destructors和object-file的区别
constructors/destructors 在您的程序是
从多个目标文件构建。
标记为'T'的符号(__libc_csu_init,__libc_csu_fini,_fini )
是“全局的”(外部可见),其余部分(标记为't')不是。
当用 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-like 编程语言的特性,但也可以在 C 中访问它们。它可能看起来过于复杂,因为其中一些代表了遗留包袱,而一些变体需要支持 GCC 运行 所采用的各种不同架构。
从你的列表中,一个接一个(或两个接两个):
00000000004003f0 t deregister_tm_clones
0000000000400430 t register_tm_clones
事务内存旨在简化线程编程。 它是 lock-based 同步的替代方法。 这些例程分别拆除和设置支持这些功能的库 (libitm) 使用的 table。 有关 TM 的更多信息,请点击此处 https://gcc.gnu.org/wiki/TransactionalMemory and here 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
这些 运行 任何 program-level 初始化器和终结器(有点像整个程序的 constructors/destructors)。 如果您定义如下函数:
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
这是 now-deprecated 到 运行 一个 program-level (对象 file-level 实际上)析构函数的方法(有关此的一些信息可以在 man dlclose
).
构造函数对应的废弃函数是 __init
.
0000000000600668 t __frame_dummy_init_array_entry
0000000000600668 t __init_array_start
这些标记 .init_array
部分的结束和开始,其中包含指向所有 program-level 初始值设定项的指针(参见上面的 __libc_csu_init ).
0000000000600670 t __do_global_dtors_aux_fini_array_entry
0000000000600670 t __init_array_end
这些标记 .fini_array
部分的结束和开始,其中包含指向所有 program-level 终结器的指针(参见上面的 __libc_csu_fini ).
[编辑] 一些附加说明:
link http://dbp-consulting.com/tutorials/debugging/linuxProgramStartup.html (wayback machine) 来自 Jester 的问题评论包含一个漂亮的图表和一个小样本 程序说明了这些东西的总体顺序 运行 以及如何 从 C 访问其中一些功能。
术语“ctors”和“dtors”是 分别为“构造函数”和“析构函数”。
全局constructors/destructors和object-file的区别 constructors/destructors 在您的程序是 从多个目标文件构建。
标记为'T'的符号(__libc_csu_init,__libc_csu_fini,_fini ) 是“全局的”(外部可见),其余部分(标记为't')不是。