miri/shims/unix/linux/
mem.rs

1//! This follows the pattern in src/shims/unix/mem.rs: We only support uses of mremap that would
2//! correspond to valid uses of realloc.
3
4use rustc_abi::Size;
5
6use crate::*;
7
8impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
9pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
10    fn mremap(
11        &mut self,
12        old_address: &OpTy<'tcx>,
13        old_size: &OpTy<'tcx>,
14        new_size: &OpTy<'tcx>,
15        flags: &OpTy<'tcx>,
16    ) -> InterpResult<'tcx, Scalar> {
17        let this = self.eval_context_mut();
18
19        let old_address = this.read_pointer(old_address)?;
20        let old_size = this.read_target_usize(old_size)?;
21        let new_size = this.read_target_usize(new_size)?;
22        let flags = this.read_scalar(flags)?.to_i32()?;
23
24        // old_address must be a multiple of the page size
25        #[expect(clippy::arithmetic_side_effects)] // PAGE_SIZE is nonzero
26        if old_address.addr().bytes() % this.machine.page_size != 0 || new_size == 0 {
27            this.set_last_error(LibcError("EINVAL"))?;
28            return interp_ok(this.eval_libc("MAP_FAILED"));
29        }
30
31        if flags & this.eval_libc_i32("MREMAP_FIXED") != 0 {
32            throw_unsup_format!("Miri does not support mremap wth MREMAP_FIXED");
33        }
34
35        if flags & this.eval_libc_i32("MREMAP_DONTUNMAP") != 0 {
36            throw_unsup_format!("Miri does not support mremap wth MREMAP_DONTUNMAP");
37        }
38
39        if flags & this.eval_libc_i32("MREMAP_MAYMOVE") == 0 {
40            // We only support MREMAP_MAYMOVE, so not passing the flag is just a failure
41            this.set_last_error(LibcError("EINVAL"))?;
42            return interp_ok(this.eval_libc("MAP_FAILED"));
43        }
44
45        let align = this.machine.page_align();
46        let ptr = this.reallocate_ptr(
47            old_address,
48            Some((Size::from_bytes(old_size), align)),
49            Size::from_bytes(new_size),
50            align,
51            MiriMemoryKind::Mmap.into(),
52            AllocInit::Zero,
53        )?;
54
55        interp_ok(Scalar::from_pointer(ptr, this))
56    }
57}