36

生成されたオブジェクト コードをメモリから直接読み込む方法を探しています。

ファイルに書き込むと、dlopen を呼び出してそのシンボルを動的にロードしてリンクできることを理解しています。ただし、メモリ内で開始し、ディスクに書き込まれ、dlopen によってメモリに再ロードされることを考えると、これは少し回り道のように思えます。メモリ内に存在するオブジェクト コードを動的にリンクする方法があるかどうか疑問に思っています。私が言えることから、これを行うにはいくつかの異なる方法があるかもしれません:

  1. dlopen をだまして、メモリから離れることはないにもかかわらず、メモリの場所がファイルであると考えさせます。

  2. 私が探していることを行う他のシステムコールを見つけてください (これは存在しないと思います)。

  3. コードをメモリ内で直接リンクできる動的リンク ライブラリを見つけます。明らかに、これはグーグルで検索するのが少し難しいです.「動的リンクライブラリ」は、動的リンクのタスクを実行するライブラリではなく、ライブラリを動的にリンクする方法に関する情報を表示するためです.

  4. リンカーから一部の API を抽象化し、そのコードベースから新しいライブラリを作成します。(明らかに、これは私にとって最も望ましくないオプションです)。

それで、これらのうちどれが可能ですか?実現可能ですか?私が仮説を立てたもののどれかを教えていただけますか? 私が考えもしなかった別の方法はありますか?

4

5 に答える 5

10

dlopenロード用にディスク上に適切なオブジェクト形式 (ELF など) を生成するために、より多くの移植性のないコードが必要になるため、なぜあなたが を検討するのかわかりません。アーキテクチャ用のマシン コードを生成する方法が既にわかっている場合は、mmapメモリを使用しPROT_READ|PROT_WRITE|PROT_EXECてコードを配置し、アドレスを関数ポインタに割り当てて呼び出します。とてもシンプルです。

于 2011-02-19T22:39:52.607 に答える
8

ファイルを書き出してから、を使用して再度ロードする以外に、これを行う標準的な方法はありませんdlopen()

現在の特定のプラットフォームで別の方法を見つけることができます。それが「標準的で(比較的)ポータブルな」アプローチを使用するよりも優れているかどうかを判断するのはあなた次第です。

そもそもオブジェクトコードの生成はプラットフォーム固有であるため、追加のプラットフォーム固有の手法は重要ではない場合があります。しかし、それは判断の呼びかけです-そして、いずれにせよ、比較的ありそうもない非標準的な技術があることに依存します。

于 2011-02-19T21:36:20.993 に答える
2

メモリ内に生成されたコードは既にメモリ内にあるため、ロードする必要はありません。

ただし、ポータブルではない方法で、メモリ内にマシンコードを生成できます(フラグ付きでmmapPROT_EXECされたメモリセグメント内にある場合)。

(その場合、特に外部関数を呼び出すために、明確な絶対アドレスまたは相対アドレスを使用してマシンコードを生成するため、「リンク」または再配置の手順は必要ありません)

それを行ういくつかのライブラリが存在します: x86またはx86-64の GNU/Linux では、GNU Lightning (低速で実行されるマシン コードをすばやく生成する)、DotGNU LibJIT (中品質のコードを生成する)、およびLLVM & GCCJIT (これはメモリ内で非常に最適化されたコードを生成できますが、それを発行するには時間がかかります)。LuaJitにも同様の機能があります2015 年以降、GCC 5 にはgccjitライブラリがあります。

もちろん、C コードをファイルに生成し、コンパイラを fork して共有オブジェクトにコンパイルし、その共有オブジェクト ファイルを dlopen することもできます。GCCを拡張するためのドメイン固有言語であるGCC MELTでそれを行っています。実際には非常にうまく機能します。

補遺

生成された C ファイルの書き込みのパフォーマンスが懸念される場合 (C ファイルのコンパイルは書き込みよりもはるかに遅いため、そうすべきではありません)、そのために何らかのtmpfsファイル システムを使用することを検討してください (おそらく、Linux ではtmpfs/tmp/ファイル システムであることが多いでしょう)。

于 2011-10-24T19:23:56.940 に答える