Auto merge of #1845 - Smittyvb:fix-after-mir-alloc-oom, r=RalfJung
Make work with latest rustc Cc https://github.com/rust-lang/rust/issues/86863, which was caused by PR https://github.com/rust-lang/rust/pull/86255.
This commit is contained in:
commit
15e81a94b1
@ -1 +1 @@
|
||||
46ae6ee65df19c6a3fb683499c1203e749975e60
|
||||
39e20f1ae5f13451eb35247808d6a2527cb7d060
|
||||
|
14
src/eval.rs
14
src/eval.rs
@ -169,7 +169,8 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
|
||||
// Make space for `0` terminator.
|
||||
let size = u64::try_from(arg.len()).unwrap().checked_add(1).unwrap();
|
||||
let arg_type = tcx.mk_array(tcx.types.u8, size);
|
||||
let arg_place = ecx.allocate(ecx.layout_of(arg_type)?, MiriMemoryKind::Machine.into());
|
||||
let arg_place =
|
||||
ecx.allocate(ecx.layout_of(arg_type)?, MiriMemoryKind::Machine.into())?;
|
||||
ecx.write_os_str_to_c_str(OsStr::new(arg), arg_place.ptr, size)?;
|
||||
argvs.push(arg_place.ptr);
|
||||
}
|
||||
@ -177,7 +178,7 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
|
||||
let argvs_layout = ecx.layout_of(
|
||||
tcx.mk_array(tcx.mk_imm_ptr(tcx.types.u8), u64::try_from(argvs.len()).unwrap()),
|
||||
)?;
|
||||
let argvs_place = ecx.allocate(argvs_layout, MiriMemoryKind::Machine.into());
|
||||
let argvs_place = ecx.allocate(argvs_layout, MiriMemoryKind::Machine.into())?;
|
||||
for (idx, arg) in argvs.into_iter().enumerate() {
|
||||
let place = ecx.mplace_field(&argvs_place, idx)?;
|
||||
ecx.write_scalar(arg, &place.into())?;
|
||||
@ -188,14 +189,14 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
|
||||
// Store `argc` and `argv` for macOS `_NSGetArg{c,v}`.
|
||||
{
|
||||
let argc_place =
|
||||
ecx.allocate(ecx.machine.layouts.isize, MiriMemoryKind::Machine.into());
|
||||
ecx.allocate(ecx.machine.layouts.isize, MiriMemoryKind::Machine.into())?;
|
||||
ecx.write_scalar(argc, &argc_place.into())?;
|
||||
ecx.machine.argc = Some(argc_place.ptr);
|
||||
|
||||
let argv_place = ecx.allocate(
|
||||
ecx.layout_of(tcx.mk_imm_ptr(tcx.types.unit))?,
|
||||
MiriMemoryKind::Machine.into(),
|
||||
);
|
||||
)?;
|
||||
ecx.write_scalar(argv, &argv_place.into())?;
|
||||
ecx.machine.argv = Some(argv_place.ptr);
|
||||
}
|
||||
@ -214,7 +215,8 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
|
||||
|
||||
let cmd_utf16: Vec<u16> = cmd.encode_utf16().collect();
|
||||
let cmd_type = tcx.mk_array(tcx.types.u16, u64::try_from(cmd_utf16.len()).unwrap());
|
||||
let cmd_place = ecx.allocate(ecx.layout_of(cmd_type)?, MiriMemoryKind::Machine.into());
|
||||
let cmd_place =
|
||||
ecx.allocate(ecx.layout_of(cmd_type)?, MiriMemoryKind::Machine.into())?;
|
||||
ecx.machine.cmd_line = Some(cmd_place.ptr);
|
||||
// Store the UTF-16 string. We just allocated so we know the bounds are fine.
|
||||
for (idx, &c) in cmd_utf16.iter().enumerate() {
|
||||
@ -226,7 +228,7 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
|
||||
};
|
||||
|
||||
// Return place (in static memory so that it does not count as leak).
|
||||
let ret_place = ecx.allocate(ecx.machine.layouts.isize, MiriMemoryKind::Machine.into());
|
||||
let ret_place = ecx.allocate(ecx.machine.layouts.isize, MiriMemoryKind::Machine.into())?;
|
||||
// Call start function.
|
||||
ecx.call_function(
|
||||
start_instance,
|
||||
|
@ -440,7 +440,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
|
||||
} else {
|
||||
// Allocate new place, set initial value to 0.
|
||||
let errno_layout = this.machine.layouts.u32;
|
||||
let errno_place = this.allocate(errno_layout, MiriMemoryKind::Machine.into());
|
||||
let errno_place = this.allocate(errno_layout, MiriMemoryKind::Machine.into())?;
|
||||
this.write_scalar(Scalar::from_u32(0), &errno_place.into())?;
|
||||
this.active_thread_mut().last_error = Some(errno_place);
|
||||
Ok(errno_place)
|
||||
|
@ -199,7 +199,7 @@ impl MemoryExtra {
|
||||
// "__cxa_thread_atexit_impl"
|
||||
// This should be all-zero, pointer-sized.
|
||||
let layout = this.machine.layouts.usize;
|
||||
let place = this.allocate(layout, MiriMemoryKind::ExternStatic.into());
|
||||
let place = this.allocate(layout, MiriMemoryKind::ExternStatic.into())?;
|
||||
this.write_scalar(Scalar::from_machine_usize(0, this), &place.into())?;
|
||||
Self::add_extern_static(this, "__cxa_thread_atexit_impl", place.ptr);
|
||||
// "environ"
|
||||
@ -213,7 +213,7 @@ impl MemoryExtra {
|
||||
// "_tls_used"
|
||||
// This is some obscure hack that is part of the Windows TLS story. It's a `u8`.
|
||||
let layout = this.machine.layouts.u8;
|
||||
let place = this.allocate(layout, MiriMemoryKind::ExternStatic.into());
|
||||
let place = this.allocate(layout, MiriMemoryKind::ExternStatic.into())?;
|
||||
this.write_scalar(Scalar::from_u8(0), &place.into())?;
|
||||
Self::add_extern_static(this, "_tls_used", place.ptr);
|
||||
}
|
||||
@ -377,6 +377,8 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'mir, 'tcx> {
|
||||
|
||||
const GLOBAL_KIND: Option<MiriMemoryKind> = Some(MiriMemoryKind::Global);
|
||||
|
||||
const PANIC_ON_ALLOC_FAIL: bool = false;
|
||||
|
||||
#[inline(always)]
|
||||
fn enforce_alignment(memory_extra: &MemoryExtra) -> bool {
|
||||
memory_extra.check_alignment != AlignmentCheck::None
|
||||
|
@ -57,7 +57,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
|
||||
let array_ty = tcx.mk_array(ptr_ty, ptrs.len().try_into().unwrap());
|
||||
|
||||
// Write pointers into array
|
||||
let alloc = this.allocate(this.layout_of(array_ty).unwrap(), MiriMemoryKind::Rust.into());
|
||||
let alloc =
|
||||
this.allocate(this.layout_of(array_ty).unwrap(), MiriMemoryKind::Rust.into())?;
|
||||
for (i, ptr) in ptrs.into_iter().enumerate() {
|
||||
let place = this.mplace_index(&alloc, i as u64)?;
|
||||
this.write_immediate_to_mplace(ptr.into(), &place)?;
|
||||
|
@ -88,7 +88,7 @@ fn alloc_env_var_as_c_str<'mir, 'tcx>(
|
||||
let mut name_osstring = name.to_os_string();
|
||||
name_osstring.push("=");
|
||||
name_osstring.push(value);
|
||||
Ok(ecx.alloc_os_str_as_c_str(name_osstring.as_os_str(), MiriMemoryKind::Env.into()))
|
||||
ecx.alloc_os_str_as_c_str(name_osstring.as_os_str(), MiriMemoryKind::Env.into())
|
||||
}
|
||||
|
||||
fn alloc_env_var_as_wide_str<'mir, 'tcx>(
|
||||
@ -99,7 +99,7 @@ fn alloc_env_var_as_wide_str<'mir, 'tcx>(
|
||||
let mut name_osstring = name.to_os_string();
|
||||
name_osstring.push("=");
|
||||
name_osstring.push(value);
|
||||
Ok(ecx.alloc_os_str_as_wide_str(name_osstring.as_os_str(), MiriMemoryKind::Env.into()))
|
||||
ecx.alloc_os_str_as_wide_str(name_osstring.as_os_str(), MiriMemoryKind::Env.into())
|
||||
}
|
||||
|
||||
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {}
|
||||
@ -179,7 +179,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
|
||||
}
|
||||
// Allocate environment block & Store environment variables to environment block.
|
||||
// Final null terminator(block terminator) is added by `alloc_os_str_to_wide_str`.
|
||||
let envblock_ptr = this.alloc_os_str_as_wide_str(&env_vars, MiriMemoryKind::Env.into());
|
||||
let envblock_ptr = this.alloc_os_str_as_wide_str(&env_vars, MiriMemoryKind::Env.into())?;
|
||||
// If the function succeeds, the return value is a pointer to the environment block of the current process.
|
||||
Ok(envblock_ptr.into())
|
||||
}
|
||||
@ -442,7 +442,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
|
||||
// No `environ` allocated yet, let's do that.
|
||||
// This is memory backing an extern static, hence `ExternStatic`, not `Env`.
|
||||
let layout = this.machine.layouts.usize;
|
||||
let place = this.allocate(layout, MiriMemoryKind::ExternStatic.into());
|
||||
let place = this.allocate(layout, MiriMemoryKind::ExternStatic.into())?;
|
||||
this.machine.env_vars.environ = Some(place);
|
||||
}
|
||||
|
||||
@ -455,7 +455,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
|
||||
let tcx = this.tcx;
|
||||
let vars_layout =
|
||||
this.layout_of(tcx.mk_array(tcx.types.usize, u64::try_from(vars.len()).unwrap()))?;
|
||||
let vars_place = this.allocate(vars_layout, MiriMemoryKind::Env.into());
|
||||
let vars_place = this.allocate(vars_layout, MiriMemoryKind::Env.into())?;
|
||||
for (idx, var) in vars.into_iter().enumerate() {
|
||||
let place = this.mplace_field(&vars_place, idx)?;
|
||||
this.write_scalar(var, &place.into())?;
|
||||
|
@ -67,18 +67,23 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
|
||||
Align::from_bytes(prev_power_of_two(size)).unwrap()
|
||||
}
|
||||
|
||||
fn malloc(&mut self, size: u64, zero_init: bool, kind: MiriMemoryKind) -> Scalar<Tag> {
|
||||
fn malloc(
|
||||
&mut self,
|
||||
size: u64,
|
||||
zero_init: bool,
|
||||
kind: MiriMemoryKind,
|
||||
) -> InterpResult<'tcx, Scalar<Tag>> {
|
||||
let this = self.eval_context_mut();
|
||||
if size == 0 {
|
||||
Scalar::null_ptr(this)
|
||||
Ok(Scalar::null_ptr(this))
|
||||
} else {
|
||||
let align = this.min_align(size, kind);
|
||||
let ptr = this.memory.allocate(Size::from_bytes(size), align, kind.into());
|
||||
let ptr = this.memory.allocate(Size::from_bytes(size), align, kind.into())?;
|
||||
if zero_init {
|
||||
// We just allocated this, the access is definitely in-bounds.
|
||||
this.memory.write_bytes(ptr.into(), iter::repeat(0u8).take(size as usize)).unwrap();
|
||||
}
|
||||
Scalar::Ptr(ptr)
|
||||
Ok(Scalar::Ptr(ptr))
|
||||
}
|
||||
}
|
||||
|
||||
@ -104,7 +109,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
|
||||
Ok(Scalar::null_ptr(this))
|
||||
} else {
|
||||
let new_ptr =
|
||||
this.memory.allocate(Size::from_bytes(new_size), new_align, kind.into());
|
||||
this.memory.allocate(Size::from_bytes(new_size), new_align, kind.into())?;
|
||||
Ok(Scalar::Ptr(new_ptr))
|
||||
}
|
||||
} else {
|
||||
@ -331,7 +336,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
|
||||
"malloc" => {
|
||||
let &[ref size] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
||||
let size = this.read_scalar(size)?.to_machine_usize(this)?;
|
||||
let res = this.malloc(size, /*zero_init:*/ false, MiriMemoryKind::C);
|
||||
let res = this.malloc(size, /*zero_init:*/ false, MiriMemoryKind::C)?;
|
||||
this.write_scalar(res, dest)?;
|
||||
}
|
||||
"calloc" => {
|
||||
@ -340,7 +345,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
|
||||
let len = this.read_scalar(len)?.to_machine_usize(this)?;
|
||||
let size =
|
||||
items.checked_mul(len).ok_or_else(|| err_ub_format!("overflow during calloc size computation"))?;
|
||||
let res = this.malloc(size, /*zero_init:*/ true, MiriMemoryKind::C);
|
||||
let res = this.malloc(size, /*zero_init:*/ true, MiriMemoryKind::C)?;
|
||||
this.write_scalar(res, dest)?;
|
||||
}
|
||||
"free" => {
|
||||
@ -368,7 +373,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
|
||||
Size::from_bytes(size),
|
||||
Align::from_bytes(align).unwrap(),
|
||||
MiriMemoryKind::Rust.into(),
|
||||
);
|
||||
)?;
|
||||
this.write_scalar(ptr, dest)?;
|
||||
}
|
||||
"__rust_alloc_zeroed" => {
|
||||
@ -380,7 +385,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
|
||||
Size::from_bytes(size),
|
||||
Align::from_bytes(align).unwrap(),
|
||||
MiriMemoryKind::Rust.into(),
|
||||
);
|
||||
)?;
|
||||
// We just allocated this, the access is definitely in-bounds.
|
||||
this.memory.write_bytes(ptr.into(), iter::repeat(0u8).take(usize::try_from(size).unwrap())).unwrap();
|
||||
this.write_scalar(ptr, dest)?;
|
||||
|
@ -161,14 +161,14 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
|
||||
&mut self,
|
||||
os_str: &OsStr,
|
||||
memkind: MemoryKind<MiriMemoryKind>,
|
||||
) -> Pointer<Tag> {
|
||||
) -> InterpResult<'tcx, Pointer<Tag>> {
|
||||
let size = u64::try_from(os_str.len()).unwrap().checked_add(1).unwrap(); // Make space for `0` terminator.
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
let arg_type = this.tcx.mk_array(this.tcx.types.u8, size);
|
||||
let arg_place = this.allocate(this.layout_of(arg_type).unwrap(), memkind);
|
||||
let arg_place = this.allocate(this.layout_of(arg_type).unwrap(), memkind)?;
|
||||
assert!(self.write_os_str_to_c_str(os_str, arg_place.ptr, size).unwrap().0);
|
||||
arg_place.ptr.assert_ptr()
|
||||
Ok(arg_place.ptr.assert_ptr())
|
||||
}
|
||||
|
||||
/// Allocate enough memory to store the given `OsStr` as a null-terminated sequence of `u16`.
|
||||
@ -176,14 +176,14 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
|
||||
&mut self,
|
||||
os_str: &OsStr,
|
||||
memkind: MemoryKind<MiriMemoryKind>,
|
||||
) -> Pointer<Tag> {
|
||||
) -> InterpResult<'tcx, Pointer<Tag>> {
|
||||
let size = u64::try_from(os_str.len()).unwrap().checked_add(1).unwrap(); // Make space for `0x0000` terminator.
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
let arg_type = this.tcx.mk_array(this.tcx.types.u16, size);
|
||||
let arg_place = this.allocate(this.layout_of(arg_type).unwrap(), memkind);
|
||||
let arg_place = this.allocate(this.layout_of(arg_type).unwrap(), memkind)?;
|
||||
assert!(self.write_os_str_to_wide_str(os_str, arg_place.ptr, size).unwrap().0);
|
||||
arg_place.ptr.assert_ptr()
|
||||
Ok(arg_place.ptr.assert_ptr())
|
||||
}
|
||||
|
||||
/// Read a null-terminated sequence of bytes, and perform path separator conversion if needed.
|
||||
|
@ -159,7 +159,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
|
||||
Size::from_bytes(size),
|
||||
Align::from_bytes(align).unwrap(),
|
||||
MiriMemoryKind::C.into(),
|
||||
);
|
||||
)?;
|
||||
this.write_scalar(ptr, &ret.into())?;
|
||||
}
|
||||
this.write_null(dest)?;
|
||||
|
@ -47,7 +47,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
|
||||
// pthread_join below) because the Rust standard library does not use
|
||||
// it.
|
||||
let ret_place =
|
||||
this.allocate(this.layout_of(this.tcx.types.usize)?, MiriMemoryKind::Machine.into());
|
||||
this.allocate(this.layout_of(this.tcx.types.usize)?, MiriMemoryKind::Machine.into())?;
|
||||
|
||||
this.call_function(
|
||||
instance,
|
||||
|
@ -115,7 +115,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
|
||||
let flags = this.read_scalar(flags)?.to_u32()?;
|
||||
let size = this.read_scalar(size)?.to_machine_usize(this)?;
|
||||
let zero_init = (flags & 0x00000008) != 0; // HEAP_ZERO_MEMORY
|
||||
let res = this.malloc(size, zero_init, MiriMemoryKind::WinHeap);
|
||||
let res = this.malloc(size, zero_init, MiriMemoryKind::WinHeap)?;
|
||||
this.write_scalar(res, dest)?;
|
||||
}
|
||||
"HeapFree" => {
|
||||
|
Loading…
x
Reference in New Issue
Block a user