2012-06-20 20 views
8

私は別のスタックでC関数を呼び出す方法を探しています。つまり、現在のスタックポインタを保存し、スタックポインタを別の場所に設定し、古いスタックポインタが戻ったときにそれを復元します。異なるスタックポインタ(gcc)を使ってC関数を呼び出す

これは、プログラミング言語用の軽量なスレッドシステムです。スレッドは非常に小さなスタックで動作し、スタックがいつ必要になるかチェックし、動的にサイズを変更します。これは、たくさんのメモリを浪費することなく、何千ものスレッドを割り当てることができるようにするためです。 Cコードを呼び出すときは、小さなコードスタックを使用するのは安全ではありません。なぜなら、Cコードはチェックとサイズ変更を知らないので、C言語用の軽量スレッド間で共有される大きなpthreadスタックを使用したいのです。同じpthread)。

これで、うまく動作するアセンブリコードスタブを書くことができましたが、gcc拡張や既に実装されているライブラリなど、これを行うためのより良い方法があるかどうかは疑問でした。もしそうでなければ、私は頭をABIやアセンブリ言語のマニュアルに埋もれさせるでしょう;-)私はこれを怠惰から頼りにして、輪を再構築したくはありません。

+0

クローンのシステムコールを使用して、個別のスタックで独自の「スレッド」を実装できます。 libcラッパーの代わりにダイレクトシステムコールを使用すると、どのリソースと名前空間が共有されているかを指定できる点を除けばforkのように動作します。 – technosaurus

答えて

2

POSIXスレッドとPOSIXシステムを使用していると仮定すると、これをシグナルで実現できます。代替信号処理スタック(sigaltstack)をセットアップし、特別なリアルタイム信号を指定して、ハンドラを代替信号スタック上で実行させます。次に、raise信号をスタックに切り替え、シグナルハンドラが呼び出す関数のデータとそれを渡す引数をスレッドローカルデータから読み取らせます。

このアプローチはかなり高価です(スタックを変更する複数のシステムコール)が、POSIXシステムに対して100%移植可能であることに注意してください。遅いので、アセンブリ固有のcall-on-alt-stack関数を作成し、アセンブリバージョンを書いていないarchのフォールバックとしてのみ私の一般的なソリューションを使用したいと思うかもしれません。

+0

これは興味深い考えですが、システムコールを使用するので高価すぎるのです。とにかく返信いただきありがとうございます。 –

+0

あなたが心配しているCPUのためにasmを書いてもよければ、まともなフォールバックを提供するかもしれません。また、古い「makecontext」API(2008年に廃止されたPOSIX 2001では廃止)を最初のフォールバックとして考えることができます。これはユーザー空間で完全に行うことができるからです。 –

+0

一般に、独自のスタックを設定し、いくつかのアセンブリスタブを使用してコンテキストを入れ替えることができます。ただし、スタックポインタが特定のメモリ範囲内にあることを強制する「スタックチェック」を実行することがあります。スタック・リミット(スタック・リミットがプラットフォームに格納されている場合はどこでも)とスタック・ポインタをスワップする必要があります。たとえば、ウィンドウでは、GSセグメントの_TIB :: StackLimitと_TIB :: StackBaseにあります。 – doug65536

関連する問題