为什么gcc默认将crtbegin.o和crtend.o链接到每个编译的可执行文件

问题描述 投票:1回答:1

为了理解POSIX libc实现的来龙去脉,我在过去一年左右的时间里一直在尝试自己的技术,认为我在自己的技能范围内摸索着Single Unix Specification的实现。制定前进的计划,我现在要下一步创建一个运行时库。

现在,我试图了解如何将程序链接到c运行时库的逻辑。

阅读gcc手册中有关初始化以及elf格式文本和嵌入式系统上一些文本的内容,我基本上已经了解到,初始化代码进入了它自己的部分.init和.fini,crti.o和crtn.o通常包含通过调用链接器脚本应该定义的函数指针列表中指定的一系列函数来使crtbegin和crtend充实的函数存根。

[这使我提出了一个问题,假设我的上述总结正确无误,以这种方式专门设计init和fini函数的逻辑如下所述:

函数(__init)的序言出现在crti.o的.init节中;结语出现在crtn.o中。对于.fini部分中的函数__fini同样。通常,这些文件由操作系统或GNU C库提供,但由GCC为一些目标提供。 (对于大多数目标而言)对象crtbegin.o和crtend.o是从crtstuff.c编译的。除其他外,它们包含.init和.fini部分中的代码片段,这些代码片段分支到.text部分中的例程。链接器会将部分的所有部分放到一起,从而产生一个完整的__init函数,该函数调用启动时所需的例程。

为什么库的init和fini函数不直接直接调用库的初始化和销毁​​函数,而不是将它们列出在链接器脚本中并在多个目标文件中散布该节的位?

链接器列表中列出的功能也是从哪里来的。从下面引用的引用中,我假设这些函数特定于crt,以说将std [in,out,err]文件描述符与文件流相关联或将locale_t变量初始化为C语言环境等,如果是这样的话函数已存储。

链接器必须建立这些功能的两个列表-初始化功能列表称为CTOR_LIST和终止功能列表称为DTOR_LIST

c gcc ld libc
1个回答
0
投票
为什么库的init和fini函数不直接直接调用库的初始化和销毁​​函数,而不是将它们列出在链接器脚本中并在多个目标文件中散布该节的位?
© www.soinside.com 2019 - 2024. All rights reserved.