どのLLVM IRコードが前に実行されるかについての一般的なルールを知っている人はいますmain
か?
Clang++ 3.6 を使用すると、オブジェクト ファイルの「.text.startup」セクションの関数を介してグローバル クラス変数のコンストラクターが呼び出されるようです。例えば:
define internal void @__cxx_global_var_init() section ".text.startup" {
call void @_ZN7MyClassC2Ev(%class.MyClass* @M)
ret void
}
この例から、 を指定する IR 関数定義を正確に探す必要があると思いますsection ".text.startup"
。
私の理論が正しいと疑う理由は 2 つあります。
LLVM IR ファイルには他に何も表示されません (
.ll)
LLVM が「__cxx_global_var_init」のような C++ 固有の関数名をスニッフィングしていないと仮定する場合、グローバル オブジェクト コンストラクターを最初に実行する必要があることを示唆しています。したがってsection ".text.startup"
、唯一の明白な手段はmain()
しかし、それが正しいとしても、関数を の前に実行させるための十分な条件を特定しましたが、それmain()
が LLVM IR で関数を の前に実行させる唯一の方法であることを示していませんmain()
。Gnu リンカは、場合によっては、セクションの最初の命令を
.text
プログラムのエントリ ポイントとして使用します。 Raspberry Pi プログラミングに関するこの記事では、コードを最初に実行する手段として、.text.startup
コンテンツをプログラムのセクションに表示される最初のコード本体にする方法について説明しています。.text
.text.startup
残念ながら、私の理論を裏付けるものは他にあまり見つかりません。
文字列「.startup」の LLVM 3.6 ソース コードを grep すると、LLVM コードの CLang 固有の部分でしか見つかりません。私の理論が正しいとすれば、LLVM コードの他の部分でもその文字列が見つかったはずです。特に、C++ フロントエンド以外の部分です。
C++ でのデータ初期化に関するこの記事は、".text.startup" に特別な役割があることを暗示しているようですが、Linux プログラム ローダーが実際にその名前のセクションを探すとは言えません。あったとしても、プラットフォームに中立な LLVM IR で特別な意味を持つ Linux 固有の可能性のあるセクション名を見つけたら驚くでしょう。
Linux 3.13.0 のソース コードには文字列 ".startup" が含まれていないようです。これは、プログラム ローダーが ".text.startup" という名前のセクションをスニッフィングしていないことを示唆しています。