Commit 76b4e49178

Andrew Kelley <andrew@ziglang.org>
2019-03-01 02:11:36
add mprotect syscall
1 parent 9753e87
Changed files (2)
std
std/os/linux/index.zig
@@ -806,6 +806,10 @@ pub fn mmap(address: ?[*]u8, length: usize, prot: usize, flags: u32, fd: i32, of
     return syscall6(SYS_mmap, @ptrToInt(address), length, prot, flags, @bitCast(usize, isize(fd)), @bitCast(usize, offset));
 }
 
+pub fn mprotect(address: usize, length: usize, protection: usize) usize {
+    return syscall3(SYS_mprotect, address, length, protection);
+}
+
 pub fn munmap(address: usize, length: usize) usize {
     return syscall2(SYS_munmap, address, length);
 }
std/os/index.zig
@@ -3406,3 +3406,27 @@ pub fn linuxINotifyRmWatch(inotify_fd: i32, wd: i32) !void {
         else => unreachable,
     }
 }
+
+pub const MProtectError = error{
+    AccessDenied,
+    OutOfMemory,
+    Unexpected,
+};
+
+/// address and length must be page-aligned
+pub fn posixMProtect(address: usize, length: usize, protection: u32) MProtectError!void {
+    const negative_page_size = @bitCast(usize, -isize(page_size));
+    const aligned_address = address & negative_page_size;
+    const aligned_end = (address + length + page_size - 1) & negative_page_size;
+    assert(address == aligned_address);
+    assert(length == aligned_end - aligned_address);
+    const rc = posix.mprotect(address, length, protection);
+    const err = posix.getErrno(rc);
+    switch (err) {
+        0 => return,
+        posix.EINVAL => unreachable,
+        posix.EACCES => return error.AccessDenied,
+        posix.ENOMEM => return error.OutOfMemory,
+        else => return unexpectedErrorPosix(err),
+    }
+}