我正在为Mac OS X编写Mac OS 9“兼容层”,因为我最近对此感到震惊,并且因为当前所有解决方案都要求您在虚拟机内运行Classic,而该虚拟机不支持它应该运行的所有内容我想要使用的东西。
为了实现这一目标,我实现了一个PEF可执行加载器,一个可以桥接到本机代码的PowerPC解释器,以及一些Mac OS 9库。整个事情都有点工作:解释器中有一些错误,但这是预期的,我正在努力。
到目前为止,我最大的问题是PowerPC程序是32位,所以指针需要是32位。为了满足这个约束,目前我只为i386编译。但是,当我试图围绕该核心进行构建时,它变得越来越受限制(例如,您不能将ARC与32位Cocoa应用程序一起使用)。更不用说让PowerPC代码访问主机进程可以访问的所有东西都不是超级安全的。
我设计了“平台”,最终切换到64位:解释器需要一个基地址,所有PowerPC指针都被该基地址偏移。 (出于性能和设计原因,有一个将PowerPC地址转换为本地地址的地图是不可能的。)
由于64位地址空间有足够的空间容纳四十亿个独立的32位地址空间,这听起来像是一个很好的方法。
但我仍然有一个问题:我需要确保我能够在该地址范围内分配内存,因为PPC解释器不可能访问它之外的任何内容。
我现在正在考虑两种解决方案:
mmap
,但是mmap
会要求以页面倍数进行分配,这对我来说似乎非常浪费,因为我需要为每个分配创建一个完整的页面,无论它多么小(虽然考虑到经典时代的Macs与现代计算机相比内存非常少,但实际上可能没问题; mmap
保留带有PROT_NONE
的完整0x100000000字节,然后根据需要mprotect
页面在需要时实际分配内存,并在需要时将它们放回PROT_NONE
它们不再有用了。它在纸面上看起来不错,但这意味着我必须实现malloc
替换。那么,我该怎么办?是否有内置机制让我尝试在特定地址范围内分配内存malloc
- 样式?否则,是否有一个良好的,可读的,开源的[{1}}实现我可以自己做什么?
答案 0 :(得分:4)
我不知道有一种内置的方法可以做到这一点,但它可以通过一些工作来实现。一种方法是创建自定义malloc区域,然后在分配需要对PPC代码可见的任何内存时使用通常malloc函数的malloc_zone_ *版本。您的自定义区域需要malloc实现,但您可以从任意数量的开源实例中选择(例如tcmalloc)。它还需要连接到使用类似vm_allocate的提示地址,以确保您在所需的确切范围内获得分配。
答案 1 :(得分:0)
所以,我自己考虑过一个非常类似的(未发布的)项目,并试图使用这个64位方法(或者,实际上x86上的任何类型的大端内存空间!)快速进入几个讨厌的问题。
虽然您可以在仿真结构中指向本机API,但您无法强制它们在该领域内进行所有自己的分配。您可以提供所有最明显的实现,例如_NewPointer
,但其他功能的内部分配(例如,_NewWindow
和wStorage
)很大程度上是您无法控制的
由模拟代码分配的系统结构(例如一个Rect)将是big-endian,但操作系统会希望它们是little-endian。除了可能在进出本机函数的过程中进行字节交换之外,没有简单的方法来解决这个问题,这似乎非常容易出错。 (我在这里考虑的另一种方法是让模拟核心运行为小端,但不幸的是,有些程序对这种变化很敏感。)
要明确的是,我喜欢Classic-to-OS-X API转换器的想法。但我很确定这是不切实际的 - 鉴于Apple在PPC上结束使用VM for Classic,我怀疑他们确定翻译方法不起作用。