gcc添加到linux ELF的功能是什么?

Vic*_*voy 26 c linux assembly gcc 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
Run Code Online (Sandbox Code Playgroud)

他们是什么,为了什么?是在某处描述的吗?谷歌搜索没有帮助.

Joh*_*all 29

其中大多数是在"主"程序本身之前或之后执行代码的各种方法,大多数方法都存在于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
Run Code Online (Sandbox Code Playgroud)

事务性内存旨在使线程编程更简单.它是基于锁的同步的替代方案.这些例程分别拆除和设置由支持这些功能的库(libitm)使用的表.有关TM的更多信息,请访问https://gcc.gnu.org/wiki/TransactionalMemoryhttp://pmarlier.free.fr/gcc-tm-tut.html

 

0000000000400470 t __do_global_dtors_aux
Run Code Online (Sandbox Code Playgroud)

.fini_array没有可用系统的程序退出程序时运行所有全局析构函数.

 

0000000000400490 t frame_dummy
Run Code Online (Sandbox Code Playgroud)

此功能位于该.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
Run Code Online (Sandbox Code Playgroud)

它们运行任何程序级初始化程序和终结程序(类似于整个程序的构造函数/析构函数).如果您定义如下函数:

void __attribute__ ((constructor)) mefirst () {
    /* ... do something here ... */
}

void __attribute__ ((destructor)) melast () {
    /* ... do something here ... */
}
Run Code Online (Sandbox Code Playgroud)

它们将main()分别在这些例程之前和之后被调用.另见https://gcc.gnu.org/onlinedocs/gccint/Initialization.html

 

0000000000400554 T _fini
Run Code Online (Sandbox Code Playgroud)

这是一种现已弃用的方式来运行程序级(实际上是对象文件级)析构函数(可以在其中找到一些信息man dlclose).构造函数的相应过时函数是__init.

 

0000000000600668 t __frame_dummy_init_array_entry
0000000000600668 t __init_array_start
Run Code Online (Sandbox Code Playgroud)

这些标记该.init_array节的结束和开始,其中包含指向所有程序级初始值设定项的指针(请参阅上面的__libc_csu_init).

 

0000000000600670 t __do_global_dtors_aux_fini_array_entry
0000000000600670 t __init_array_end
Run Code Online (Sandbox Code Playgroud)

这些标记该.fini_array节的结束和开始,其中包含指向所有程序级终结器的指针(请参阅上面的__libc_csu_fini).

 

[编辑]一些附加说明:

  • 来自Jester问题评论的链接 http://dbp-consulting.com/tutorials/debugging/linuxProgramStartup.html包含一个很好的图表和一个小示例程序,说明了这些内容的整体运行顺序以及如何访问其中的一些功能来自C.

  • 术语" ctors "和" dtors "分别是" 构造函数 "和" 析构函数 "的缩写.

  • 当程序由多个目标文件构造时,全局构造函数/析构函数和目标文件构造函数/析构函数之间的区别最为明显.

  • 标记为" T " 的符号(__libc_csu_init,__ libc_csu_fini,_fini)是"全局"(外部可见),而不是("标记为" t ')的符号.