背景:
個人的なプロジェクトとして、C++ でカーネルを開発しています。順調に進んでいます。実際、私はカーネル ランドで利用可能な多くの C++ を非常によくサポートしています (libc と libstdc++ のほぼ全体を実装しました)。
より困難でコンパイラ固有のものの 1 つは、RTTI と例外のサポートです。今のところ、例外を完全に無効にしていますが、RTTI などはdynamic_cast
非常に便利なので、RTTI が必要です。これを機能させるために、g++ が期待するものと一致する std::type_info の基本的な実装を用意してから、g++ のlibsupc++.a
andにリンクしlibgcc_eh.a
ます。これはうまくいきます。RTTI はチャンピオンのように機能します。
質問:
私はいくつかの最適化オプションをいじっていましたが、いつか -mregparm をコンパイル時の選択肢として使用したいと考えています。明らかに、これはカーネルであり、アセンブリ コードと対話する必要があります。スタックにパラメーターがない場合、適切に機能しない特定の関数があります。これを解決するために、次のマクロを使用します。
#define asmlinkage attribute((regparm(0)))
繰り返しますが、これは非常にうまく機能します。問題は、dynamic_cast
. コンパイルは、いくつかの暗黙的に定義された内部関数 (前述のサポート ライブラリで定義されている) への呼び出しを発行し、-mregparm フラグを考慮して行います。もちろん、私はシステムのサポート ライブラリにリンクしているので、互換性のある呼び出し規約がある場合とない場合があります (私の場合はありません)。これらの関数は暗黙的 (どのファイルにもプロトタイプがない) であり、長くて壊れた名前を持っているため、asmlinkage 属性をそれらに追加することは (ほぼ) 不可能です。
頭に浮かぶ3つの可能な解決策があります。
- -mregparm を一緒にサポートすることを忘れてください。
- これら 2 つのサポート ライブラリをカーネルと同じフラグで再コンパイルします。これは煩わしく、少し非現実的かもしれません (gcc ビルドからきれいに分離できるかどうかはわかりませんし、ツールチェーンのアップグレードは非常に苦痛になる可能性があります) が、うまくいくはずです。
- 特定の .a/.o ファイルにあるコードを呼び出すときに、何らかの方法でコンパイラが -mregparm を無視するようにします。
オプション3は可能ですか?私の直感はノーですが、ここにはいくつかのg ++の専門家がいるので、私は尋ねると思いました:-)。