88//! else that goes beyond a basic allocation API.
99
1010use crate :: * ;
11- use rustc_target:: abi:: { Align , Size } ;
11+ use rustc_target:: abi:: Size ;
1212
1313impl < ' mir , ' tcx : ' mir > EvalContextExt < ' mir , ' tcx > for crate :: MiriInterpCx < ' mir , ' tcx > { }
1414pub trait EvalContextExt < ' mir , ' tcx : ' mir > : crate :: MiriInterpCxExt < ' mir , ' tcx > {
@@ -88,7 +88,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
8888 throw_unsup_format ! ( "Miri does not support non-zero offsets to mmap" ) ;
8989 }
9090
91- let align = Align :: from_bytes ( this. machine . page_size ) . unwrap ( ) ;
91+ let align = this. machine . page_align ( ) ;
9292 let map_length = this. machine . round_up_to_multiple_of_page_size ( length) . unwrap_or ( u64:: MAX ) ;
9393
9494 let ptr =
@@ -115,14 +115,14 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
115115 ) -> InterpResult < ' tcx , Scalar < Provenance > > {
116116 let this = self . eval_context_mut ( ) ;
117117
118- let old_address = this. read_pointer ( old_address) ?;
118+ let old_address = this. read_scalar ( old_address) ? . to_target_usize ( this ) ?;
119119 let old_size = this. read_scalar ( old_size) ?. to_target_usize ( this) ?;
120120 let new_size = this. read_scalar ( new_size) ?. to_target_usize ( this) ?;
121121 let flags = this. read_scalar ( flags) ?. to_i32 ( ) ?;
122122
123123 // old_address must be a multiple of the page size
124124 #[ allow( clippy:: arithmetic_side_effects) ] // PAGE_SIZE is nonzero
125- if old_address. addr ( ) . bytes ( ) % this. machine . page_size != 0 || new_size == 0 {
125+ if old_address % this. machine . page_size != 0 || new_size == 0 {
126126 this. set_last_error ( Scalar :: from_i32 ( this. eval_libc_i32 ( "EINVAL" ) ) ) ?;
127127 return Ok ( this. eval_libc ( "MAP_FAILED" ) ) ;
128128 }
@@ -141,6 +141,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
141141 return Ok ( Scalar :: from_maybe_pointer ( Pointer :: null ( ) , this) ) ;
142142 }
143143
144+ let old_address = Machine :: ptr_from_addr_cast ( this, old_address) ?;
144145 let align = this. machine . page_align ( ) ;
145146 let ptr = this. reallocate_ptr (
146147 old_address,
@@ -171,57 +172,41 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
171172 ) -> InterpResult < ' tcx , Scalar < Provenance > > {
172173 let this = self . eval_context_mut ( ) ;
173174
174- let addr = this. read_pointer ( addr) ?;
175+ let addr = this. read_scalar ( addr) ? . to_target_usize ( this ) ?;
175176 let length = this. read_scalar ( length) ?. to_target_usize ( this) ?;
176177
177178 // addr must be a multiple of the page size
178179 #[ allow( clippy:: arithmetic_side_effects) ] // PAGE_SIZE is nonzero
179- if addr. addr ( ) . bytes ( ) % this. machine . page_size != 0 {
180+ if addr % this. machine . page_size != 0 {
180181 this. set_last_error ( Scalar :: from_i32 ( this. eval_libc_i32 ( "EINVAL" ) ) ) ?;
181182 return Ok ( Scalar :: from_i32 ( -1 ) ) ;
182183 }
183184
184185 let length = this. machine . round_up_to_multiple_of_page_size ( length) . unwrap_or ( u64:: MAX ) ;
185186
186- let mut addr = addr. addr ( ) . bytes ( ) ;
187- let mut bytes_unmapped = 0 ;
188- while bytes_unmapped < length {
189- // munmap specifies:
190- // It is not an error if the indicated range does not contain any mapped pages.
191- // So we make sure that if our address is not that of an exposed allocation, we just
192- // step forward to the next page.
193- let ptr = Machine :: ptr_from_addr_cast ( this, addr) ?;
194- let Ok ( ptr) = ptr. into_pointer_or_addr ( ) else {
195- bytes_unmapped = bytes_unmapped. checked_add ( this. machine . page_size ) . unwrap ( ) ;
196- addr = addr. wrapping_add ( this. machine . page_size ) ;
197- continue ;
198- } ;
199- // FIXME: This should fail if the pointer is to an unexposed allocation. But it
200- // doesn't.
201- let Some ( ( alloc_id, offset, _prov) ) = Machine :: ptr_get_alloc ( this, ptr) else {
202- bytes_unmapped = bytes_unmapped. checked_add ( this. machine . page_size ) . unwrap ( ) ;
203- addr = addr. wrapping_add ( this. machine . page_size ) ;
204- continue ;
205- } ;
206-
207- if offset != Size :: ZERO {
208- throw_unsup_format ! ( "Miri does not support partial munmap" ) ;
209- }
210- let ( _kind, alloc) = this. memory . alloc_map ( ) . get ( alloc_id) . unwrap ( ) ;
211- let this_alloc_len = alloc. len ( ) as u64 ;
212- bytes_unmapped = bytes_unmapped. checked_add ( this_alloc_len) . unwrap ( ) ;
213- if bytes_unmapped > length {
214- throw_unsup_format ! ( "Miri does not support partial munmap" ) ;
215- }
216-
217- this. deallocate_ptr (
218- Pointer :: new ( Some ( Provenance :: Wildcard ) , Size :: from_bytes ( addr) ) ,
219- Some ( ( Size :: from_bytes ( this_alloc_len) , this. machine . page_align ( ) ) ) ,
220- MemoryKind :: Machine ( MiriMemoryKind :: Mmap ) ,
221- ) ?;
222- addr = addr. wrapping_add ( this_alloc_len) ;
187+ let ptr = Machine :: ptr_from_addr_cast ( this, addr) ?;
188+
189+ let Ok ( ptr) = ptr. into_pointer_or_addr ( ) else {
190+ throw_unsup_format ! ( "Miri only supports munmap on memory allocated directly by mmap" ) ;
191+ } ;
192+ let Some ( ( alloc_id, offset, _prov) ) = Machine :: ptr_get_alloc ( this, ptr) else {
193+ throw_unsup_format ! ( "Miri only supports munmap on memory allocated directly by mmap" ) ;
194+ } ;
195+
196+ let ( _kind, alloc) = this. memory . alloc_map ( ) . get ( alloc_id) . unwrap ( ) ;
197+ if offset != Size :: ZERO || alloc. len ( ) as u64 != length {
198+ throw_unsup_format ! (
199+ "Miri only supports munmap calls that exactly unmap a region previously returned by mmap"
200+ ) ;
223201 }
224202
203+ let len = Size :: from_bytes ( alloc. len ( ) as u64 ) ;
204+ this. deallocate_ptr (
205+ Pointer :: new ( Some ( Provenance :: Wildcard ) , Size :: from_bytes ( addr) ) ,
206+ Some ( ( len, this. machine . page_align ( ) ) ) ,
207+ MemoryKind :: Machine ( MiriMemoryKind :: Mmap ) ,
208+ ) ?;
209+
225210 Ok ( Scalar :: from_i32 ( 0 ) )
226211 }
227212}
0 commit comments