LLVM IR 中的哪些代码在 "main()" 之前运行?
Which code in LLVM IR runs before "main()"?
有谁知道 main
之前将执行哪些 LLVM IR 代码的一般规则?
使用 Clang++ 3.6 时,似乎全局 class 变量通过目标文件的“.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 不是' t 嗅探特定于 C++ 的函数名称,如“__cxx_global_var_init”。所以 section ".text.startup"
是唯一明显的表示代码应该在 main()
之前 运行 的方法,但即使这是正确的,我们已经确定了一个 足够 条件来使函数在 main()
之前达到 运行,但没有证明这是 LLVM IR 中导致的唯一方法main()
.
之前 运行 的函数
Raspberry Pi 编程中的 Gnu 链接器 in some cases, will use the first instruction in the .text
section to be the program entry point. This article 描述了使 .text.startup
内容成为程序 [=19= 中出现的第一个代码体] 部分,作为使 .text.startup
代码首先变为 运行 的一种方法。
不幸的是,我没有找到更多支持我的理论的东西:
当我 grep LLVM 3.6 源代码中的字符串“.startup”时,我只在 LLVM 代码的 CLang 特定部分找到它。为了使我的理论正确,我希望在 LLVM 代码的其他部分也能找到该字符串;特别是 C++ 前端之外的部分。
data initialization in C++上的这篇文章似乎暗示“.text.startup”有特殊作用,但并没有直接说Linux 程序加载器实际上会查找该名称的一部分。即使是这样,我也会惊讶地发现一个潜在的 Linux 特定的部分名称在平台中立的 LLVM IR 中具有特殊含义。
Linux 3.13.0 源代码似乎不包含字符串“.startup”,向我暗示程序加载器没有嗅探带有名称“.text.startup”.
答案很简单——LLVM 不在幕后执行任何事情。这是 C runtime (CRT) to perform all necessary preparations before running main(). This includes (but not limited to) to static ctors and similar things. The runtime is usually informed about these objects via addresses of constructores being emitted in the special sections (e.g. .init_array or .ctors). See e.g. http://wiki.osdev.org/Calling_Global_Constructors 的工作以获取更多信息。
有谁知道 main
之前将执行哪些 LLVM IR 代码的一般规则?
使用 Clang++ 3.6 时,似乎全局 class 变量通过目标文件的“.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 不是' t 嗅探特定于 C++ 的函数名称,如“__cxx_global_var_init”。所以section ".text.startup"
是唯一明显的表示代码应该在main()
之前 运行 的方法,但即使这是正确的,我们已经确定了一个 足够 条件来使函数在main()
之前达到 运行,但没有证明这是 LLVM IR 中导致的唯一方法main()
. 之前 运行 的函数
Raspberry Pi 编程中的 Gnu 链接器 in some cases, will use the first instruction in the
.text
section to be the program entry point. This article 描述了使.text.startup
内容成为程序 [=19= 中出现的第一个代码体] 部分,作为使.text.startup
代码首先变为 运行 的一种方法。
不幸的是,我没有找到更多支持我的理论的东西:
当我 grep LLVM 3.6 源代码中的字符串“.startup”时,我只在 LLVM 代码的 CLang 特定部分找到它。为了使我的理论正确,我希望在 LLVM 代码的其他部分也能找到该字符串;特别是 C++ 前端之外的部分。
data initialization in C++上的这篇文章似乎暗示“.text.startup”有特殊作用,但并没有直接说Linux 程序加载器实际上会查找该名称的一部分。即使是这样,我也会惊讶地发现一个潜在的 Linux 特定的部分名称在平台中立的 LLVM IR 中具有特殊含义。
Linux 3.13.0 源代码似乎不包含字符串“.startup”,向我暗示程序加载器没有嗅探带有名称“.text.startup”.
答案很简单——LLVM 不在幕后执行任何事情。这是 C runtime (CRT) to perform all necessary preparations before running main(). This includes (but not limited to) to static ctors and similar things. The runtime is usually informed about these objects via addresses of constructores being emitted in the special sections (e.g. .init_array or .ctors). See e.g. http://wiki.osdev.org/Calling_Global_Constructors 的工作以获取更多信息。