1

背景:

個人的なプロジェクトとして、C++ でカーネルを開発しています。順調に進んでいます。実際、私はカーネル ランドで利用可能な多くの C++ を非常によくサポートしています (libc と libstdc++ のほぼ全体を実装しました)。

より困難でコンパイラ固有のものの 1 つは、RTTI と例外のサポートです。今のところ、例外を完全に無効にしていますが、RTTI などはdynamic_cast非常に便利なので、RTTI が必要です。これを機能させるために、g++ が期待するものと一致する std::type_info の基本的な実装を用意してから、g++ のlibsupc++.aandにリンクしlibgcc_eh.aます。これはうまくいきます。RTTI はチャンピオンのように機能します。

質問:

私はいくつかの最適化オプションをいじっていましたが、いつか -mregparm をコンパイル時の選択肢として使用したいと考えています。明らかに、これはカーネルであり、アセンブリ コードと対話する必要があります。スタックにパラメーターがない場合、適切に機能しない特定の関数があります。これを解決するために、次のマクロを使用します。

#define asmlinkage  attribute((regparm(0)))

繰り返しますが、これは非常にうまく機能します。問題は、dynamic_cast. コンパイルは、いくつかの暗黙的に定義された内部関数 (前述のサポート ライブラリで定義されている) への呼び出しを発行し、-mregparm フラグを考慮して行います。もちろん、私はシステムのサポート ライブラリにリンクしているので、互換性のある呼び出し規約がある場合とない場合があります (私の場合はありません)。これらの関数は暗黙的 (どのファイルにもプロトタイプがない) であり、長くて壊れた名前を持っているため、asmlinkage 属性をそれらに追加することは (ほぼ) 不可能です。

頭に浮かぶ3つの可能な解決策があります。

  1. -mregparm を一緒にサポートすることを忘れてください。
  2. これら 2 つのサポート ライブラリをカーネルと同じフラグで再コンパイルします。これは煩わしく、少し非現実的かもしれません (gcc ビルドからきれいに分離できるかどうかはわかりませんし、ツールチェーンのアップグレードは非常に苦痛になる可能性があります) が、うまくいくはずです。
  3. 特定の .a/.o ファイルにあるコードを呼び出すときに、何らかの方法でコンパイラが -mregparm を無視するようにします。

オプション3は可能ですか?私の直感はノーですが、ここにはいくつかのg ++​​の専門家がいるので、私は尋ねると思いました:-)。

4

1 に答える 1

1

おそらく、オプション 1 または 2 を使用するのが最適です (1 の方が明らかに簡単です)。私の知る限り、g++ にはオプション 3 の特定のスイッチはありません。

于 2009-03-27T08:39:10.983 に答える