【问题标题】:__attribute__((constructor)) how it change entry point?__attribute__((constructor)) 它如何改变入口点?
【发布时间】:2018-09-06 11:19:15
【问题描述】:

我知道从 C 编程语言的角度来看 main()是程序的入口。

但从操作系统的角度来看,__start ctrt0 启动例程被链接到一个程序中,该程序在调用程序的main() 函数之前执行所需的任何初始化工作(如果这里有错误,请纠正我) .

所以我们有一些属性可以用于我们的功能,其中之一是 在main()之前调用的constructor属性,谁负责调用这个函数?

__attribute__((construtor))
void foo(void)
{
        puts("Constructor called by ... ?\n");
}

它在逐步调用堆栈中的外观如何?谢谢!

【问题讨论】:

  • 只是吹毛求疵:从操作系统的角度来看,符号__start 不是起点。从 链接器脚本 的角度来看,这是起点。然后,链接描述文件将设置链接器,以便在可执行文件的头文件中设置一个特定字段,以包含链接描述文件中提到的任何“开始”函数的地址。
  • 这显然不是标准的 C 功能,所以答案应该很清楚。而且它不会改变C程序的入口点。

标签: c gcc compilation


【解决方案1】:

标记为“构造函数”的函数放置在可执行文件的特殊部分中。然后“start”函数将在调用main之前一一调用这些函数。

与“析构”函数一样,它们再次被放置在一个特殊的部分中,并由在调用exitmain返回之后执行的代码调用。

【讨论】:

  • 实际上它们并没有放在一个特殊的部分,但它们的调用是。 IIRC 与 C++ 为静态对象调用 ctors/dtors 的机制相同(因此得名)。
  • @toohonestforthissite 这更有意义,因为它会更容易生成代码。
  • 我必须查找确切的机制,但 IIRC 有一个 glibc 函数(或用户为例如嵌入式系统提供),由 crt 调用,将部分数据解析为列表/数组或相似的。当然需要链接器等的支持。
猜你喜欢
  • 2014-05-10
  • 2022-01-06
  • 2011-01-04
  • 2015-04-23
  • 1970-01-01
  • 2012-12-28
  • 2020-05-29
  • 1970-01-01
相关资源
最近更新 更多