St.*_*rio 1 linux assembly x86-64
我正在尝试匿名映射内存页面。就这个:
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
Run Code Online (Sandbox Code Playgroud)
这是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
Run Code Online (Sandbox Code Playgroud)
我不太清楚为什么mmap我们为什么不指定MAP_PRIVATE标志就匿名映射呢?
您不需要MAP_PRIVATE,您需要MAP_PRIVATE或之一MAP_SHARED。
flags参数确定对映射的更新对于映射同一区域的其他进程是否可见,以及是否将更新进行到基础文件。通过在标志中完全包含以下值之一来确定此行为:
MAP_SHARED
分享此映射。[...]
MAP_PRIVATE
创建一个私有的写时复制映射。[...]
mmap 让您选择如何传播对映射区域所做的任何更改:
MAP_PRIVATE由文件备份
没有更新对映射同一文件的其他进程可见。
没有更新写入后备文件。将对COW页面
进行更新。
用于就地处理文件的内容。
MAP_PRIVATE | MAP_ANONYMOUS(例如,没有文件备份)
没有文件可更新。
将对COW页面进行更新。
有用,可用于分配内存,不与分支进程共享。
MAP_SHARED由文件备份的
更新其他进程可见。
更新将传播到支持文件。
对转换文件很有用。
与使用名称的其他进程共享内存区域很有用(请参见shm_open)。
MAP_SHARED | MAP_ANONYMOUS(例如,未通过文件备份)
对于映射了相同区域的所有进程,更新都是可见的。
没有要更新的文件。
与分叉的进程共享内部存储区很有用。