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

时间:2016-01-23 16:47:34

标签: c linux gcc assembly 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

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

1 个答案:

答案 0 :(得分:28)

其中大多数是在“主要”程序本身之前或之后执行代码的各种方法,大多数方法都存在于crtstuff.chttps://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/TransactionalMemoryhttp://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 )。

[编辑] 一些附加说明:

  • 链接 http://dbp-consulting.com/tutorials/debugging/linuxProgramStartup.html 来自Jester的问题评论包含一个很好的图表和一个小样本 程序说明了这些事情的总体顺序以及如何运行 从C。

  • 访问其中一些功能
  • 术语' ctors '和' dtors '是缩写 分别是'构造函数'和'析构函数

  • 全局构造函数/析构函数和对象文件之间的区别 当你的程序是,构造函数/析构函数最明显 从多个目标文件构建。

  • 标有“ T ”的符号( __ libc_csu_init,__ libc_csu_fini,_fini ) 是“全局的”(外部可见),剩余的(标记为“ t ”)不是。