gpt4 book ai didi

第四次实现 JIT 写保护?

转载 作者:行者123 更新时间:2023-12-05 04:21:55 26 4
gpt4 key购买 nike

我相信 Apple 已禁止在 ARM64 架构上同时写入和执行内存,请参阅:

参见 mmap() RWX page on MacOS (ARM64 architecture)?

这使得像 jonesforth 这样的实现很难移植,它将生成的代码和生成它的代码(如 jonesforth.f 中的内置汇编程序)保存在同一段中。

我想我可以做一些事情,比如将用户空间从开始映射到 HERE 为“r-x”,从这里到结束映射为“rw-”。然后我在编译新单词时必须不断地重新映射内存,而且我不能去修复以前的单词(我相信 SCODE 会利用它)。

对于如何处理此类限制,您有什么建议吗?

我想我应该研究一下在 M1 Mac 上运行的其他实现。

最佳答案

Forth 实现只有在生成应该立即可执行的机器代码时,才会对写保护代码段产生问题。如果使用线程代码就没有这个问题。所以下面假设Forth系统必须生成机器码。

数据空间和代码空间

  1. 显然,您必须将代码空间与data space 分开.数据空间(至少可变区域,包括变量区域和数据字段),以及内部可变内存区域和可能的 header ,应该映射到“rw-”段。代码空间应映射到“r-x”段。

  2. 单词here ( -- addr ) 返回第一个可用于保留的单元格的地址,该单元格对于程序是可写的,并且应该是始终 在“rw-”段中。如果需要,您可以使用内部字 code::here ( -- addr ) 返回代码空间中的地址。

  3. 执行 token 的决定是实现速度和简单性之间的折衷(“r-x”段与“rw-”)。最简单的情况是,一个执行 token 由一个“rw-”段中的地址表示,然后execute 进行额外的解引用以获取相应的代码地址。

代码生成

在给定的条件下,我们应该将机器代码生成为“rw-”段,但在执行此代码之前,应将此段设为“r-x”。

可能,最简单的解决方案是为每个新定义分配一个内存块,在完成时调整(最小化) block 的大小并使其成为“r-x”。可能的缺点 — 由于页面大小(例如 4 KiB)和可能的内存碎片而造成的损失。

更改从 code::here 开始的主代码段的保护也意味着由于页面大小粒度而造成的损失。

另一种变体是将定义的创建分为两个阶段:

  1. 在编译定义期间在单独的“rw-”段中生成中间表示 (IR);
  2. 定义完成后,从IR中生成主代码段的机器码,丢弃IR码。

其实第一阶段也可以是机器码,第二阶段就搬迁到别的地方了。

在写入主代码段之前,您将其(或其部分)更改为“rw-”,然后将其恢复为“r-x”。

翻译 IR 代码的子例程应该驻留在您不更改的另一个“r-x”段中。

Forth 对生成代码的格式是不可知的,在一个简单的系统中,只有少数定义“知道”生成的格式。因此,仅应更改这些定义以生成 IR 代码。如果您重新定位机器代码,您可能甚至不需要更改这些定义。

关于第四次实现 JIT 写保护?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74132150/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com