我正在尝试匿名映射一页内存。这是它:
mov rax, 0x09 ; SYS_mmap
mov rdi, 0x00 ; addr is NULL
mov rsi, 0x8000 ; x86 page_size
mov rdx, 0x02 ; PROT_WRITE
mov r10, 0x20 ; MAP_ANONYMOUS
mov r8, -1 ; fd = -1
mov r9, 0x00 ; offset = 0
syscall
mov [rax], dword -2 ; Segmentation fault, rax = -22
这是段错误。但是当我将 MAP_PRIVATE
添加到标志时它工作正常:
mov rax, 0x09 ; SYS_mmap
mov rdi, 0x00 ; addr is NULL
mov rsi, 0x8000 ; x86 page_size
mov rdx, 0x02 ; PROT_WRITE
mov r10, 0x22 ; MAP_ANONYMOUS | MAP_PRIVATE
mov r8, -1 ; fd = -1
mov r9, 0x00 ; offset = 0
syscall
mov [rax], dword -2 ; Now it works ok, rax = 0x7ffff7ff2000
我不太明白为什么 mmap
会失败,为什么我们在不指定 MAP_PRIVATE
标志的情况下进行匿名映射?
最佳答案
您不需要MAP_PRIVATE
,您需要MAP_PRIVATE
或MAP_SHARED
之一。
The flags argument determines whether updates to the mapping are visible to other processes mapping the same region, and whether updates are carried through to the underlying file. This behavior is determined by including exactly one of the following values in flags:
MAP_SHARED
Share this mapping. [...]
MAP_PRIVATE
Create a private copy-on-write mapping. [...]
mmap
让您选择如何传播对映射区域所做的任何更改:
MAP_PRIVATE
由文件备份
映射同一文件的其他进程看不到任何更新。
没有更新写入支持文件。
对 COW 进行了更新页。对于就地处理文件的内容很有用。
MAP_PRIVATE | MAP_ANONYMOUS
(例如,不由文件备份)
没有要更新的文件。
对 COW 页面进行更新。用于分配内存,不与 fork 进程共享。
MAP_SHARED
由文件备份
更新对其他进程可见。
更新被传播到支持文件。对转换文件很有用。
使用名称与其他进程共享内存区域很有用(请参阅 shm_open )。MAP_SHARED | MAP_ANONYMOUS
(例如,不由文件备份)
更新对映射到同一区域的所有进程都是可见的。
没有要更新的文件。与 fork 进程共享内部内存区域很有用。
关于linux - 为什么我们在映射内存时需要 MAP_PRIVATE 标志?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48883547/