From 76b4e49178b72fb9b01e97aa6b46f9d5bdb83ab2 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Thu, 28 Feb 2019 20:11:36 -0500 Subject: [PATCH] add mprotect syscall --- std/os/index.zig | 24 ++++++++++++++++++++++++ std/os/linux/index.zig | 4 ++++ 2 files changed, 28 insertions(+) diff --git a/std/os/index.zig b/std/os/index.zig index 148f4ebe06..e483bf2dbd 100644 --- a/std/os/index.zig +++ b/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), + } +} diff --git a/std/os/linux/index.zig b/std/os/linux/index.zig index b78c1b3da5..3a56461a40 100644 --- a/std/os/linux/index.zig +++ b/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); }