我正在尝试匿名显示一页内存。这是它:
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
这是SegFaulted。但是当我向标志添加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
失败?
答案 0 :(得分:5)
您不需要MAP_PRIVATE
,需要MAP_PRIVATE
或MAP_SHARED
之一。
flags参数确定是否对映射进行更新 映射相同区域的其他进程可见,以及是否 更新将传递到基础文件。这种行为是 通过在flags中包含以下其中一个值来确定:
MAP_SHARED
分享这个映射。 [...]
MAP_PRIVATE
创建私有的写时复制映射。 [...]
mmap
可让您选择如何传播对映射区域所做的任何更改:
MAP_PRIVATE
由文件备份
映射同一文件的其他进程无法看到更新
没有更新写入后备文件
更新到COW页面。
用于就地处理文件的内容。
MAP_PRIVATE | MAP_ANONYMOUS
(例如不由文件备份)
没有要更新的文件
更新到COW页面。
用于分配内存,不与分叉进程共享。
MAP_SHARED
由文件备份
其他进程可以看到更新
更新将传播到后备文件。
用于转换文件。
用于使用名称与其他进程共享内存区域很有用(请参阅shm_open)。
MAP_SHARED | MAP_ANONYMOUS
(例如不由文件备份)
对于映射了相同区域的所有进程,可以看到更新
没有要更新的文件。
用分叉进程共享内部存储区很有用。