12

私が Mac OS X 用に Mac OS 9 の「互換性レイヤー」を書​​いているのは、最近懐かしさに襲われたからです。現在のすべてのソリューションでは、仮想マシン内で Classic を実行する必要があり、実行する必要があるものすべてをサポートしていないためです。使いたい。

その目標を達成するために、PEF 実行可能ローダー、ネイティブ コードにブリッジできる PowerPC インタープリター、およびいくつかの Mac OS 9 ライブラリを実装しました。全体的にうまくいっています。インタプリタにいくつかのバグがありますが、それは予想されていたことであり、私はそれに取り組んでいます。

これまでの私の最大の問題は、PowerPC プログラムが 32 ビットであるため、ポインターも 32 ビットである必要があるということです。その制約を満たすために、現在私は i386 用にのみコンパイルしています。ただし、そのコアを中心に構築しようとすると、ますます制約が厳しくなります (たとえば、32 ビットの Cocoa アプリケーションで ARC を使用することはできません)。言うまでもなく、PowerPC コードがホスト プロセスがアクセスできるすべてのものにアクセスできるようにすることは、非常に安全ではありません。

最終的に 64 ビットに切り替えることを念頭に置いて「プラットフォーム」を設計しました。インタープリターはベース アドレスを予期し、すべての PowerPC ポインターはそのベース アドレスによってオフセットされます。(パフォーマンスと設計上の理由から、PowerPC アドレスをネイティブ アドレスに変換するマップを持つことは論外です。)

64 ビット アドレス空間には、40 億個の独立した 32 ビット アドレス空間をホストするのに十分なスペースがあるため、これは私にとって良い方法のように思えます。

しかし、まだ問題があります。そのアドレス範囲内にメモリを割り当てることができるようにする必要があります。PPC インタープリターがその範囲外にアクセスすることは不可能だからです。

私が今考えている解決策は2つあります。

  • 特定のアドレス範囲内に何かを割り当てるように Mac OS に依頼できるかどうか調べてください。を使用できることはわかっていますmmapmmap、ページの倍数で割り当てを要求します。これは、割り当てごとにページ全体が必要になるため、非常に無駄に思えます。当時の Mac は、現代のコンピューターに比べてメモリがほとんどありませんでした)。
  • mmapで完全な 0x100000000 バイトを予約するために使用しPROT_NONEmprotectオンデマンドでページを作成して、必要なときに実際にメモリを割り当て、不要になったときに元に戻しPROT_NONEます。紙の上では良さそうに見えますが、malloc代わりを実装する必要があるということです。

それで、私は何をすべきですか?malloc特定のアドレス範囲内にメモリを割り当てようとする組み込みのメカニズムはありますか? mallocそれ以外の場合、自分自身のベースにできる、読みやすくオープンソースの優れた実装はありますか?

4

2 に答える 2

4

これを行うための組み込みの方法は知りませんが、少し作業すれば実行可能です。1 つのアプローチは、カスタム malloc ゾーンを作成し、PPC コードに表示する必要があるメモリを割り当てるときに、通常の malloc 関数の malloc_zone_* バージョンを使用することです。カスタム ゾーンには malloc の実装が必要ですが、任意の数のオープン ソースのもの (tcmalloc など) から選択できます。また、必要な正確な範囲で割り当てを確実に取得するために、ヒント アドレスを指定して vm_allocate などを使用するように配線する必要があります。

于 2012-11-26T20:17:50.970 に答える
0

したがって、私はこの問題を非常によく似た(未公開の)プロジェクトについて自分で考えました。この64ビットアプローチ(または、x86のあらゆる種類のビッグエンディアンメモリスペース!)を使おうとすると、すぐにいくつかの厄介な問題が発生します。 。

  1. エミュレートされた構造にネイティブAPIを指定することはできますが、その領域内ですべての独自の割り当てを強制することはできません。のように、最も明白なものすべての独自の実装を提供できますが、_NewPointer他の関数(たとえば、_NewWindownilを使用wStorage)による内部割り当ては、ほとんど制御できません。

  2. エミュレートされたコードによって割り当てられるシステム構造(たとえば、Rectなど)はビッグエンディアンになりますが、OSはそれらをリトルエンディアンにする必要があります。ネイティブ関数に出入りする途中ですべてをバイトスワッピングする以外に、これを回避する簡単な方法はありません。これは非常にエラーが発生しやすいようです。(ここで検討したもう1つのアプローチは、エミュレートされたコアをリトルエンディアンとして実行することでしたが、残念ながら、一部のプログラムはこの変更に敏感です。)

明確にするために、私はClassicからOS-XへのAPIトランスレータのアイデアの地獄が大好きです。しかし、それは実用的ではないと確信しています。AppleがPPCでClassic用のVMの使用を終了したことを考えると、翻訳アプローチは機能しないと彼らが判断したのではないかと思います。

于 2012-11-23T20:33:44.283 に答える