Add generic range bounds to mmap (#110)

This commit is contained in:
Lachlan Sneff 2019-01-23 09:37:56 -08:00 committed by GitHub
parent f5407eef7c
commit 7632beced8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 42 additions and 14 deletions

View File

@ -63,7 +63,7 @@ impl FuncResolverBuilder {
.map_err(|e| CompileError::InternalError { msg: e.to_string() })?; .map_err(|e| CompileError::InternalError { msg: e.to_string() })?;
unsafe { unsafe {
memory memory
.protect(0..memory.size(), Protect::ReadWrite) .protect(.., Protect::ReadWrite)
.map_err(|e| CompileError::InternalError { msg: e.to_string() })?; .map_err(|e| CompileError::InternalError { msg: e.to_string() })?;
} }
@ -179,7 +179,7 @@ impl FuncResolverBuilder {
unsafe { unsafe {
self.resolver self.resolver
.memory .memory
.protect(0..self.resolver.memory.size(), Protect::ReadExec) .protect(.., Protect::ReadExec)
.map_err(|e| CompileError::InternalError { msg: e.to_string() })?; .map_err(|e| CompileError::InternalError { msg: e.to_string() })?;
} }

View File

@ -66,9 +66,7 @@ impl Trampolines {
let mut memory = Memory::with_size(total_size).unwrap(); let mut memory = Memory::with_size(total_size).unwrap();
unsafe { unsafe {
memory memory.protect(.., Protect::ReadWrite).unwrap();
.protect(0..memory.size(), Protect::ReadWrite)
.unwrap();
} }
// "\xCC" disassembles to "int3", which will immediately cause // "\xCC" disassembles to "int3", which will immediately cause
@ -91,7 +89,7 @@ impl Trampolines {
} }
unsafe { unsafe {
memory.protect(0..memory.size(), Protect::ReadExec).unwrap(); memory.protect(.., Protect::ReadExec).unwrap();
} }
Self { Self {

View File

@ -1,7 +1,7 @@
use errno; use errno;
use nix::libc; use nix::libc;
use page_size; use page_size;
use std::ops::Range; use std::ops::{Bound, RangeBounds};
use std::{ptr, slice}; use std::{ptr, slice};
#[derive(Debug)] #[derive(Debug)]
@ -42,13 +42,30 @@ impl Memory {
} }
} }
pub unsafe fn protect(&mut self, range: Range<usize>, protect: Protect) -> Result<(), String> { pub unsafe fn protect(
&mut self,
range: impl RangeBounds<usize>,
protect: Protect,
) -> Result<(), String> {
let protect = protect.to_protect_const(); let protect = protect.to_protect_const();
let range_start = match range.start_bound() {
Bound::Included(start) => *start,
Bound::Excluded(start) => *start,
Bound::Unbounded => 0,
};
let range_end = match range.end_bound() {
Bound::Included(end) => *end,
Bound::Excluded(end) => *end,
Bound::Unbounded => self.size(),
};
let page_size = page_size::get(); let page_size = page_size::get();
let start = self let start = self
.ptr .ptr
.add(round_down_to_page_size(range.start, page_size)); .add(round_down_to_page_size(range_start, page_size));
let size = round_up_to_page_size(range.end - range.start, page_size); let size = round_up_to_page_size(range_end - range_start, page_size);
assert!(size <= self.size); assert!(size <= self.size);
let success = libc::mprotect(start as _, size, protect as i32); let success = libc::mprotect(start as _, size, protect as i32);

View File

@ -4,7 +4,7 @@ use winapi::um::memoryapi::{
PAGE_NOACCESS, PAGE_EXECUTE_READ, PAGE_READWRITE, PAGE_READONLY, PAGE_NOACCESS, PAGE_EXECUTE_READ, PAGE_READWRITE, PAGE_READONLY,
}; };
use page_size; use page_size;
use std::ops::Range; use std::ops::{Bound, RangeBounds};
use std::{ptr, slice}; use std::{ptr, slice};
#[derive(Debug)] #[derive(Debug)]
@ -43,13 +43,26 @@ impl Memory {
} }
} }
pub unsafe fn protect(&mut self, range: Range<usize>, protect: Protect) -> Result<(), String> { pub unsafe fn protect(&mut self, range: impl RangeBounds<usize>, protect: Protect) -> Result<(), String> {
let protect = protect.to_protect_const(); let protect = protect.to_protect_const();
let range_start = match range.start_bound() {
Bound::Included(start) => *start,
Bound::Excluded(start) => *start,
Bound::Unbounded => 0,
};
let range_end = match range.end_bound() {
Bound::Included(end) => *end,
Bound::Excluded(end) => *end,
Bound::Unbounded => self.size(),
};
let page_size = page_size::get(); let page_size = page_size::get();
let start = self let start = self
.ptr .ptr
.add(round_down_to_page_size(range.start, page_size)); .add(round_down_to_page_size(range_start, page_size));
let size = round_up_to_page_size(range.end - range.start, page_size); let size = round_up_to_page_size(range_end - range_start, page_size);
assert!(size <= self.size); assert!(size <= self.size);
// Commit the virtual memory. // Commit the virtual memory.