1 use super::cvt;
2 use crate::prelude::*;
3 use crate::runtime::vm::sys::{capi, vm::MemoryImageSource};
4 use crate::runtime::vm::{HostAlignedByteCount, SendSyncPtr};
5 use core::ops::Range;
6 use core::ptr::{self, NonNull};
7 #[cfg(feature = "std")]
8 use std::{fs::File, path::Path};
9
10 #[cfg(feature = "std")]
open_file_for_mmap(_path: &Path) -> Result<File>11 pub fn open_file_for_mmap(_path: &Path) -> Result<File> {
12 crate::bail!("not supported on this platform");
13 }
14
15 #[derive(Debug)]
16 pub struct Mmap {
17 memory: SendSyncPtr<[u8]>,
18 }
19
20 impl Mmap {
new_empty() -> Mmap21 pub fn new_empty() -> Mmap {
22 Mmap {
23 memory: crate::vm::sys::empty_mmap(),
24 }
25 }
26
new(size: HostAlignedByteCount) -> Result<Self>27 pub fn new(size: HostAlignedByteCount) -> Result<Self> {
28 let mut ptr = ptr::null_mut();
29 cvt(unsafe {
30 capi::wasmtime_mmap_new(
31 size.byte_count(),
32 capi::PROT_READ | capi::PROT_WRITE,
33 &mut ptr,
34 )
35 })?;
36 let memory = ptr::slice_from_raw_parts_mut(ptr.cast(), size.byte_count());
37 let memory = SendSyncPtr::new(NonNull::new(memory).unwrap());
38 Ok(Mmap { memory })
39 }
40
reserve(size: HostAlignedByteCount) -> Result<Self>41 pub fn reserve(size: HostAlignedByteCount) -> Result<Self> {
42 let mut ptr = ptr::null_mut();
43 cvt(unsafe { capi::wasmtime_mmap_new(size.byte_count(), 0, &mut ptr) })?;
44 let memory = ptr::slice_from_raw_parts_mut(ptr.cast(), size.byte_count());
45 let memory = SendSyncPtr::new(NonNull::new(memory).unwrap());
46 Ok(Mmap { memory })
47 }
48
49 #[cfg(feature = "std")]
from_file(_file: &File) -> Result<Self>50 pub fn from_file(_file: &File) -> Result<Self> {
51 crate::bail!("not supported on this platform");
52 }
53
make_accessible( &self, start: HostAlignedByteCount, len: HostAlignedByteCount, ) -> Result<()>54 pub unsafe fn make_accessible(
55 &self,
56 start: HostAlignedByteCount,
57 len: HostAlignedByteCount,
58 ) -> Result<()> {
59 let ptr = self.memory.as_ptr();
60 unsafe {
61 cvt(capi::wasmtime_mprotect(
62 ptr.byte_add(start.byte_count()).cast(),
63 len.byte_count(),
64 capi::PROT_READ | capi::PROT_WRITE,
65 ))?;
66 }
67
68 Ok(())
69 }
70
71 #[inline]
as_send_sync_ptr(&self) -> SendSyncPtr<u8>72 pub fn as_send_sync_ptr(&self) -> SendSyncPtr<u8> {
73 self.memory.cast()
74 }
75
76 #[inline]
len(&self) -> usize77 pub fn len(&self) -> usize {
78 self.memory.as_ptr().len()
79 }
80
make_executable( &self, range: Range<usize>, enable_branch_protection: bool, ) -> Result<()>81 pub unsafe fn make_executable(
82 &self,
83 range: Range<usize>,
84 enable_branch_protection: bool,
85 ) -> Result<()> {
86 unsafe {
87 let base = self.memory.as_ptr().byte_add(range.start).cast();
88 let len = range.end - range.start;
89
90 // not mapped into the C API at this time.
91 let _ = enable_branch_protection;
92
93 cvt(capi::wasmtime_mprotect(
94 base,
95 len,
96 capi::PROT_READ | capi::PROT_EXEC,
97 ))?;
98 }
99 Ok(())
100 }
101
make_readonly(&self, range: Range<usize>) -> Result<()>102 pub unsafe fn make_readonly(&self, range: Range<usize>) -> Result<()> {
103 unsafe {
104 let base = self.memory.as_ptr().byte_add(range.start).cast();
105 let len = range.end - range.start;
106
107 cvt(capi::wasmtime_mprotect(base, len, capi::PROT_READ))?;
108 }
109 Ok(())
110 }
111
make_readwrite(&self, range: Range<usize>) -> Result<()>112 pub unsafe fn make_readwrite(&self, range: Range<usize>) -> Result<()> {
113 unsafe {
114 let base = self.memory.as_ptr().byte_add(range.start).cast();
115 let len = range.end - range.start;
116
117 cvt(capi::wasmtime_mprotect(
118 base,
119 len,
120 capi::PROT_READ | capi::PROT_WRITE,
121 ))?;
122 }
123 Ok(())
124 }
125
map_image_at( &self, image_source: &MemoryImageSource, source_offset: u64, memory_offset: HostAlignedByteCount, memory_len: HostAlignedByteCount, ) -> Result<()>126 pub unsafe fn map_image_at(
127 &self,
128 image_source: &MemoryImageSource,
129 source_offset: u64,
130 memory_offset: HostAlignedByteCount,
131 memory_len: HostAlignedByteCount,
132 ) -> Result<()> {
133 assert_eq!(source_offset, 0);
134 unsafe {
135 let base = self
136 .memory
137 .as_ptr()
138 .byte_add(memory_offset.byte_count())
139 .cast();
140 cvt(capi::wasmtime_memory_image_map_at(
141 image_source.image_ptr().as_ptr(),
142 base,
143 memory_len.byte_count(),
144 ))
145 }
146 }
147 }
148
149 impl Drop for Mmap {
drop(&mut self)150 fn drop(&mut self) {
151 unsafe {
152 let ptr = self.memory.as_ptr().cast();
153 let len = self.memory.as_ptr().len();
154 if len == 0 {
155 return;
156 }
157 cvt(capi::wasmtime_munmap(ptr, len)).unwrap();
158 }
159 }
160 }
161