LLVM IR中的哪些代码在“main()”之前运行?

时间:2015-06-17 14:21:30

标签: linux llvm elf llvm-ir ldd

有谁知道在main之前确切执行哪些LLVM IR代码的一般规则?

使用Clang ++ 3.6时,似乎全局类变量的构造函数通过目标文件的“.text.startup”部分中的函数调用。例如:

define internal void @__cxx_global_var_init() section ".text.startup" {
  call void @_ZN7MyClassC2Ev(%class.MyClass* @M)
  ret void
}

从这个例子中,我猜我应该正在寻找那些指定section ".text.startup"的IR函数定义。

我有两个理由怀疑我的理论是正确的:

  • 我的LLVM IR文件中没有看到任何其他内容(.ll),如果我们假设LLVM没有嗅探C ++特定的函数名,则建议首先运行全局对象构造函数比如“__cxx_global_var_init”。所以section ".text.startup"是表示代码应该在main()之前运行的唯一明显方法。但即使这是正确的,我们也确定了足够的条件导致函数在main()之前运行,但未显示它是LLVM IR中导致函数在main()之前运行的唯一方法。

  • Gnu链接器in some cases将使用.text部分中的第一条指令作为程序入口点。 Raspberry Pi编程的This article描述了导致.text.startup内容成为程序.text部分中出现的第一个代码体,作为导致.text.startup代码运行的一种方法第一

不幸的是,我找不到其他任何东西来支持我的理论:

  • 当我为字符串“.startup”grep LLVM 3.6源代码时,我只能在LLVM代码的CLang特定部分中找到它。为了使我的理论正确,我希望在LLVM代码的其他部分也找到该字符串;特别是C ++前端之外的部分。

  • 这篇关于data initialization in C++的文章似乎暗示了“.text.startup”有一个特殊的角色,但它并没有说明Linux程序加载器实际上是在找一段那个名字。即使它确实如此,我也会惊讶地发现一个特定于Linux的部分名称在平台中立的LLVM IR中具有特殊含义。

  • Linux 3.13.0源代码似乎不包含字符串“.startup”,向我建议程序加载程序不会嗅探名为“.text.startup”的部分。

1 个答案:

答案 0 :(得分:4)

答案很简单 - LLVM没有在幕后执行任何操作。在运行main()之前执行所有必要的准备工作是C cancelPressed()(CRT)的工作。这包括(但不限于)静态ctors和类似的东西。通常通过在特殊部分(例如.init_array或.ctors)中发出的构造函数的地址来通知运行时这些对象。参见例如runtime了解更多信息。