1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
|
use {
crate::util::fits_usize,
std::{
mem::{align_of, size_of},
ops::Range,
ptr::NonNull,
slice::{from_raw_parts, from_raw_parts_mut},
},
};
/// Get sub-range of memory mapping.
/// `range` and `fitting` are in memory object space.
/// `ptr` points to the `range.start` offset from memory origin.
/// returns pointer to `fitting.start` offset from memory origin
/// if `fitting` is contained in `range`.
pub(crate) fn mapped_sub_range(
ptr: NonNull<u8>,
range: Range<u64>,
fitting: Range<u64>,
) -> Option<NonNull<u8>> {
assert!(
range.start < range.end,
"Memory mapping region must have valid size"
);
assert!(
fitting.start < fitting.end,
"Memory mapping region must have valid size"
);
assert!(fits_usize(range.end - range.start));
assert!(usize::max_value() - (range.end - range.start) as usize >= ptr.as_ptr() as usize);
if fitting.start < range.start || fitting.end > range.end {
None
} else {
Some(unsafe {
// for x > 0 and y >= 0: x + y > 0. No overflow due to checks above.
NonNull::new_unchecked(
(ptr.as_ptr() as usize + (fitting.start - range.start) as usize) as *mut u8,
)
})
}
}
/// # Safety
///
/// User must ensure that:
/// * this function won't create aliasing slices.
/// * returned slice doesn't outlive mapping.
/// * `T` Must be plain-old-data type compatible with data in mapped region.
pub(crate) unsafe fn mapped_slice_mut<'a, T>(ptr: NonNull<u8>, size: usize) -> &'a mut [T] {
assert_eq!(
size % size_of::<T>(),
0,
"Range length must be multiple of element size"
);
let offset = ptr.as_ptr() as usize;
assert_eq!(
offset % align_of::<T>(),
0,
"Range offset must be multiple of element alignment"
);
assert!(usize::max_value() - size >= ptr.as_ptr() as usize);
from_raw_parts_mut(ptr.as_ptr() as *mut T, size)
}
/// # Safety
///
/// User must ensure that:
/// * returned slice doesn't outlive mapping.
/// * `T` Must be plain-old-data type compatible with data in mapped region.
pub(crate) unsafe fn mapped_slice<'a, T>(ptr: NonNull<u8>, size: usize) -> &'a [T] {
assert_eq!(
size % size_of::<T>(),
0,
"Range length must be multiple of element size"
);
let offset = ptr.as_ptr() as usize;
assert_eq!(
offset % align_of::<T>(),
0,
"Range offset must be multiple of element alignment"
);
assert!(usize::max_value() - size >= ptr.as_ptr() as usize);
from_raw_parts(ptr.as_ptr() as *const T, size)
}
|