无法在 MacOS 上使用 MAP_32BIT 创建匿名映射

Posted

技术标签:

【中文标题】无法在 MacOS 上使用 MAP_32BIT 创建匿名映射【英文标题】:Cannot create anonymous mapping with MAP_32BIT on MacOS 【发布时间】:2021-12-15 20:28:29 【问题描述】:

我使用的是 64 位系统,但想使用 mmap 在前 2GB 内存中分配页面。在 Linux 上,我可以使用 MAP_32BIT 标志来做到这一点:

#include <sys/mman.h>
#include <stdio.h>

int main() 
    void *addr = mmap(
        NULL, // address hint
        4096, // size
        PROT_READ | PROT_WRITE, // permissions
        MAP_32BIT | MAP_PRIVATE | MAP_ANONYMOUS, // flags
        -1, // file descriptor
        0 // offset
    );
    if (addr == MAP_FAILED)
        perror("mmap");
    else
        printf("%p", addr);

Godbolt link demonstrating that this works on Linux。从 10.15 版开始,MacOS also allegedly supports the MAP_32BIT flag。但是,当我在我的系统 (11.3) 上编译和运行该程序时,它会以 ENOMEM 失败。删除MAP_32BIT 后,映射确实有效。

对于为什么这不起作用,我有一些可能的解释,但没有一个是非常有说服力的:

权限有问题(尽管删除 PROT_READPROT_WRITE 都没有解决问题)。 出于某种原因,我需要为此指定地址提示。 MacOS(或我的版本)根本不支持 MAP_32BIT 进行匿名映射。

【问题讨论】:

帖子中没有解决的一个明显问题:没有MAP_32BIT 是否可以工作? @kaylum 确实如此;我可以编辑问题以反映这一点。 【参考方案1】:

问题在于“零页”:在某些 32 位 Unix 上,内存的最低页通常配置为不可访问,以便可以检测到对 NULL 的访问并发出错误信号。在 64 位系统上,MacOS 默认将此扩展到整个前 4 GiB 内存。 mmap 因此拒绝映射该区域中的地址,因为它们已经映射到第 0 页。

这可以使用链接器选项简单地更改:

$ cc -Wl,-pagezero_size,0x1000 test.c
$ ./a.out
0xb0e5000

【讨论】:

以上是关于无法在 MacOS 上使用 MAP_32BIT 创建匿名映射的主要内容,如果未能解决你的问题,请参考以下文章

c++17 map::extract 方法在 macOS 上可用吗?

在 windows 10 32bit 上安装 rabbitmq

使用C ++ 11的chrono和_USE_32BIT_TIME_T

无法在 Perl 5.32.0 MacOS Sierra 上安装 Test::File

大数据处理-Bitmap

无法在 macOS 10.13 上启动 AVD