-46ae6ee65df19c6a3fb683499c1203e749975e60
+39e20f1ae5f13451eb35247808d6a2527cb7d060
// 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);
}
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())?;
// 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);
}
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() {
};
// 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,
} 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)
// "__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"
// "_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);
}
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
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)?;
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>(
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> {}
}
// 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())
}
// 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);
}
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())?;
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))
}
}
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 {
"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" => {
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" => {
Size::from_bytes(size),
Align::from_bytes(align).unwrap(),
MiriMemoryKind::Rust.into(),
- );
+ )?;
this.write_scalar(ptr, dest)?;
}
"__rust_alloc_zeroed" => {
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)?;
&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`.
&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.
Size::from_bytes(size),
Align::from_bytes(align).unwrap(),
MiriMemoryKind::C.into(),
- );
+ )?;
this.write_scalar(ptr, &ret.into())?;
}
this.write_null(dest)?;
// 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,
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" => {