Skip to content

Commit

Permalink
Factor out the redundancy between test_mmap and test_mmap64.
Browse files Browse the repository at this point in the history
  • Loading branch information
sunfishcode committed Feb 10, 2024
1 parent a6f1dba commit aa40634
Showing 1 changed file with 24 additions and 127 deletions.
151 changes: 24 additions & 127 deletions src/tools/miri/tests/pass-dep/shims/mmap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,128 +5,25 @@
use std::io::Error;
use std::{ptr, slice};

fn test_mmap() {
fn test_mmap<Offset: Default>(
mmap: unsafe extern "C" fn(
*mut libc::c_void,
libc::size_t,
libc::c_int,
libc::c_int,
libc::c_int,
Offset,
) -> *mut libc::c_void,
) {
let page_size = page_size::get();
let ptr = unsafe {
libc::mmap(
ptr::null_mut(),
page_size,
libc::PROT_READ | libc::PROT_WRITE,
libc::MAP_PRIVATE | libc::MAP_ANONYMOUS,
-1,
0,
)
};
assert!(!ptr.is_null());

// Ensure that freshly mapped allocations are zeroed
let slice = unsafe { slice::from_raw_parts_mut(ptr as *mut u8, page_size) };
assert!(slice.iter().all(|b| *b == 0));

// Do some writes, make sure they worked
for b in slice.iter_mut() {
*b = 1;
}
assert!(slice.iter().all(|b| *b == 1));

// Ensure that we can munmap
let res = unsafe { libc::munmap(ptr, page_size) };
assert_eq!(res, 0i32);

// Test all of our error conditions
let ptr = unsafe {
libc::mmap(
ptr::null_mut(),
page_size,
libc::PROT_READ | libc::PROT_WRITE,
libc::MAP_PRIVATE | libc::MAP_SHARED, // Can't be both private and shared
-1,
0,
)
};
assert_eq!(ptr, libc::MAP_FAILED);
assert_eq!(Error::last_os_error().raw_os_error().unwrap(), libc::EINVAL);

let ptr = unsafe {
libc::mmap(
ptr::null_mut(),
0, // Can't map no memory
libc::PROT_READ | libc::PROT_WRITE,
libc::MAP_PRIVATE | libc::MAP_ANONYMOUS,
-1,
0,
)
};
assert_eq!(ptr, libc::MAP_FAILED);
assert_eq!(Error::last_os_error().raw_os_error().unwrap(), libc::EINVAL);

let ptr = unsafe {
libc::mmap(
ptr::invalid_mut(page_size * 64),
page_size,
libc::PROT_READ | libc::PROT_WRITE,
// We don't support MAP_FIXED
libc::MAP_PRIVATE | libc::MAP_ANONYMOUS | libc::MAP_FIXED,
-1,
0,
)
};
assert_eq!(ptr, libc::MAP_FAILED);
assert_eq!(Error::last_os_error().raw_os_error().unwrap(), libc::ENOTSUP);

// We don't support protections other than read+write
for prot in [libc::PROT_NONE, libc::PROT_EXEC, libc::PROT_READ, libc::PROT_WRITE] {
let ptr = unsafe {
libc::mmap(
ptr::null_mut(),
page_size,
prot,
libc::MAP_PRIVATE | libc::MAP_ANONYMOUS,
-1,
0,
)
};
assert_eq!(ptr, libc::MAP_FAILED);
assert_eq!(Error::last_os_error().raw_os_error().unwrap(), libc::ENOTSUP);
}

// We report an error for mappings whose length cannot be rounded up to a multiple of
// the page size.
let ptr = unsafe {
libc::mmap(
ptr::null_mut(),
usize::MAX - 1,
libc::PROT_READ | libc::PROT_WRITE,
libc::MAP_PRIVATE | libc::MAP_ANONYMOUS,
-1,
0,
)
};
assert_eq!(ptr, libc::MAP_FAILED);

// We report an error when trying to munmap an address which is not a multiple of the page size
let res = unsafe { libc::munmap(ptr::invalid_mut(1), page_size) };
assert_eq!(res, -1);
assert_eq!(Error::last_os_error().raw_os_error().unwrap(), libc::EINVAL);

// We report an error when trying to munmap a length that cannot be rounded up to a multiple of
// the page size.
let res = unsafe { libc::munmap(ptr::invalid_mut(page_size), usize::MAX - 1) };
assert_eq!(res, -1);
assert_eq!(Error::last_os_error().raw_os_error().unwrap(), libc::EINVAL);
}

#[cfg(target_os = "linux")]
fn test_mmap64() {
let page_size = page_size::get();
let ptr = unsafe {
libc::mmap64(
mmap(
ptr::null_mut(),
page_size,
libc::PROT_READ | libc::PROT_WRITE,
libc::MAP_PRIVATE | libc::MAP_ANONYMOUS,
-1,
0,
Default::default(),
)
};
assert!(!ptr.is_null());
Expand All @@ -147,40 +44,40 @@ fn test_mmap64() {

// Test all of our error conditions
let ptr = unsafe {
libc::mmap64(
mmap(
ptr::null_mut(),
page_size,
libc::PROT_READ | libc::PROT_WRITE,
libc::MAP_PRIVATE | libc::MAP_SHARED, // Can't be both private and shared
-1,
0,
Default::default(),
)
};
assert_eq!(ptr, libc::MAP_FAILED);
assert_eq!(Error::last_os_error().raw_os_error().unwrap(), libc::EINVAL);

let ptr = unsafe {
libc::mmap64(
mmap(
ptr::null_mut(),
0, // Can't map no memory
libc::PROT_READ | libc::PROT_WRITE,
libc::MAP_PRIVATE | libc::MAP_ANONYMOUS,
-1,
0,
Default::default(),
)
};
assert_eq!(ptr, libc::MAP_FAILED);
assert_eq!(Error::last_os_error().raw_os_error().unwrap(), libc::EINVAL);

let ptr = unsafe {
libc::mmap64(
mmap(
ptr::invalid_mut(page_size * 64),
page_size,
libc::PROT_READ | libc::PROT_WRITE,
// We don't support MAP_FIXED
libc::MAP_PRIVATE | libc::MAP_ANONYMOUS | libc::MAP_FIXED,
-1,
0,
Default::default(),
)
};
assert_eq!(ptr, libc::MAP_FAILED);
Expand All @@ -189,13 +86,13 @@ fn test_mmap64() {
// We don't support protections other than read+write
for prot in [libc::PROT_NONE, libc::PROT_EXEC, libc::PROT_READ, libc::PROT_WRITE] {
let ptr = unsafe {
libc::mmap64(
mmap(
ptr::null_mut(),
page_size,
prot,
libc::MAP_PRIVATE | libc::MAP_ANONYMOUS,
-1,
0,
Default::default(),
)
};
assert_eq!(ptr, libc::MAP_FAILED);
Expand All @@ -205,13 +102,13 @@ fn test_mmap64() {
// We report an error for mappings whose length cannot be rounded up to a multiple of
// the page size.
let ptr = unsafe {
libc::mmap64(
mmap(
ptr::null_mut(),
usize::MAX - 1,
libc::PROT_READ | libc::PROT_WRITE,
libc::MAP_PRIVATE | libc::MAP_ANONYMOUS,
-1,
0,
Default::default(),
)
};
assert_eq!(ptr, libc::MAP_FAILED);
Expand Down Expand Up @@ -275,9 +172,9 @@ fn test_mremap() {
}

fn main() {
test_mmap();
test_mmap(libc::mmap);
#[cfg(target_os = "linux")]
test_mmap64();
test_mmap(libc::mmap64);
#[cfg(target_os = "linux")]
test_mremap();
}

0 comments on commit aa40634

Please sign in to comment.