You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MacOS ARM64架构下mmap创建RWX页面失败求助

解决ARM64 macOS下mmap映射RWX内存失败的问题

在ARM64架构的macOS上,苹果强制启用W^X(写或执行二选一)的内存安全机制,即使禁用SIP也无法直接映射同时可写可执行的内存页,这就是你收到EACCES错误的核心原因。x64 Catalina允许直接映射RWX是因为旧架构的安全规则相对宽松,但ARM64从设计上就严格执行W^X机制。

针对你的FORTH自修改代码需求,正确的操作流程是分两步完成:


1. 先映射可读写(RW)内存页

先申请一块仅可读写的内存区域,用于生成或修改代码:

mov x0, 0                   // 让内核自动分配起始地址
    mov x1, 4096                // 内存页长度(4KB)
    mov x2, 0x3                 // 权限:PROT_READ | PROT_WRITE (0x1 | 0x2)
    mov x3, 0x1001              // flags:MAP_PRIVATE | MAP_ANON (0x1000 | 0x1)
    mov x4, -1                  // 文件描述符:-1对应匿名映射
    mov x5, 0                   // 文件偏移:0(匿名映射无需关心)
    mov x16, 0x200005c          // mmap系统调用号
    svc 0

    // 检查返回值:若x0为-1(即0xFFFFFFFFFFFFFFF),说明映射失败
    cmp x0, #-1
    b.eq mmap_fail

2. 将内存权限修改为可读可执行(RX)

当代码生成完成后,调用mprotect将内存权限切换为可执行:

// x0保留第一步mmap返回的内存起始地址
    mov x1, 4096                // 要修改权限的内存长度
    mov x2, 0x5                 // 权限:PROT_READ | PROT_EXEC (0x1 | 0x4)
    mov x16, 0x200005d          // mprotect系统调用号
    svc 0

    // 检查返回值:0表示成功,-1表示失败
    cmp x0, #-1
    b.eq mprotect_fail

如果后续需要再次修改这段代码,只需重复反向操作:

  • 调用mprotect将权限改回RW(0x3)
  • 修改代码内容
  • 再次调用mprotect改回RX(0x5)

这种方式完全适配FORTH运行时自修改代码的需求,同时符合ARM64 macOS的内存安全规则。

内容的提问来源于stack exchange,提问作者Klapaucius Klapaucius

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 11:11:17