12

我正在为 Mac OS X 编写一个 Mac OS 9“兼容层”,因为我最近被怀旧之情所震撼,而且因为所有当前的解决方案都要求您在虚拟机中运行 Classic,而该虚拟机不支持运行我应该运行的东西的所有内容想用。

为了实现这个目标,我实现了一个 PEF 可执行加载器、一个可以桥接到本机代码的 PowerPC 解释器以及一些 Mac OS 9 库。整个事情有点工作:解释器中有一些错误,但这是意料之中的,我正在努力。

到目前为止,我最大的问题是 PowerPC 程序是 32 位的,所以指针必须是 32 位的。为了满足这个限制,目前我只为 i386 编译。然而,当我试图围绕该核心进行构建时,它变得越来越受限制(例如,您不能将 ARC 与 32 位 Cocoa 应用程序一起使用)。更不用说让 PowerPC 代码访问主机进程可以访问的所有内容并不是超级安全的。

我在设计“平台”时考虑到最终切换到 64 位:解释器需要一个基地址,并且所有 PowerPC 指针都被该基地址偏移。(出于性能和设计原因,拥有将 PowerPC 地址转换为本地地址的映射是毫无疑问的。)

由于 64 位地址空间有足够的空间容纳 40 亿个独立的 32 位地址空间,这对我来说听起来是个不错的方法。

但是我仍然有一个问题:我需要确保我能够在该地址范围内分配内存,因为 PPC 解释器不可能访问它之外的任何内容。

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

  • 看看我是否可以要求 Mac OS 在特定地址范围内分配一些东西。我知道我可以使用mmap,但mmap会要求以页面倍数进行分配,这对我来说似乎非常浪费,因为我需要为每个分配提供一整页,无论它有多小(尽管考虑到 Classic- 这实际上可以与现代计算机相比,时代 Mac 的内存非常少);
  • 用于mmap保留完整的 0x100000000 字节PROT_NONE,然后mprotect按需分页以在需要时实际分配内存,并PROT_NONE在它们不再有用时将它们放回原处。它在纸上看起来不错,但这意味着我必须实施malloc替换。

所以我该怎么做?是否有内置机制可以让我尝试malloc在特定地址范围内分配内存?否则,是否有一个好的、可读的、开源的实现malloc我可以基于?

4

2 回答 2

4

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

于 2012-11-26T20:17:50.970 回答
0

所以,我自己考虑过这个问题,用于一个非常相似(未发布)的项目,并尝试使用这种 64 位方法(或者,实际上是 x86 上的任何类型的大端内存空间!)很快就会遇到一些令人讨厌的问题.

  1. 虽然您可以将本机 API 指向模拟结构,但您不能强制它们在该领域内进行所有自己的分配。您可以提供自己的所有最明显的实现,例如_NewPointer,但是其他函数的内部分配(例如,_NewWindow使用 nil wStorage)在很大程度上是您无法控制的。

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

需要明确的是,我非常喜欢 Classic-to-OS-X API 转换器的想法。但我很确定这是不切实际的——鉴于 Apple 最终在 PPC 上使用 VM for Classic,我怀疑他们认为翻译方法行不通。

于 2012-11-23T20:33:44.283 回答