如何让Mac OS在特定地址范围内分配内存?

时间:2012-11-22 17:13:11

标签: macos memory-management retro-computing

我正在为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解释器不可能访问它之外的任何内容。

我现在正在考虑两种解决方案:

  • 了解我是否可以要求Mac OS在特定地址范围内分配内容。我知道我可以使用mmap,但是mmap会要求以页面倍数进行分配,这对我来说似乎非常浪费,因为我需要为每个分配创建一个完整的页面,无论它多么小(虽然考虑到经典时代的Macs与现代计算机相比内存非常少,但实际上可能没问题;
  • 使用mmap保留带有PROT_NONE的完整0x100000000字节,然后根据需要mprotect页面在需要时实际分配内存,并在需要时将它们放回PROT_NONE它们不再有用了。它在纸面上看起来不错,但这意味着我必须实现malloc替换。

那么,我该怎么办?是否有内置机制让我尝试在特定地址范围内分配内存malloc - 样式?否则,是否有一个良好的,可读的,开源的[{1}}实现我可以自己做什么?

2 个答案:

答案 0 :(得分:4)

我不知道有一种内置的方法可以做到这一点,但它可以通过一些工作来实现。一种方法是创建自定义malloc区域,然后在分配需要对PPC代码可见的任何内存时使用通常malloc函数的malloc_zone_ *版本。您的自定义区域需要malloc实现,但您可以从任意数量的开源实例中选择(例如tcmalloc)。它还需要连接到使用类似vm_allocate的提示地址,以确保您在所需的确切范围内获得分配。

答案 1 :(得分:0)

所以,我自己考虑过一个非常类似的(未发布的)项目,并试图使用这个64位方法(或者,实际上x86上的任何类型的大端内存空间!)快速进入几个讨厌的问题。

  1. 虽然您可以在仿真结构中指向本机API,但您无法强制它们在该领域内进行所有自己的分配。您可以提供所有最明显的实现,例如_NewPointer,但其他功能的内部分配(例如,_NewWindowwStorage)很大程度上是您无法控制的

  2. 由模拟代码分配的系统结构(例如一个Rect)将是big-endian,但操作系统会希望它们是little-endian。除了可能在进出本机函数的过程中进行字节交换之外,没有简单的方法来解决这个问题,这似乎非常容易出错。 (我在这里考虑的另一种方法是让模拟核心运行为小端,但不幸的是,有些程序对这种变化很敏感。)

  3. 要明确的是,我喜欢Classic-to-OS-X API转换器的想法。但我很确定这是不切实际的 - 鉴于Apple在PPC上结束使用VM for Classic,我怀疑他们确定翻译方法不起作用。