]> git.lizzy.rs Git - rust.git/commitdiff
Make work after mir-alloc-oom
authorSmitty <me@smitop.com>
Sun, 4 Jul 2021 13:59:55 +0000 (09:59 -0400)
committerSmitty <me@smitop.com>
Sun, 4 Jul 2021 13:59:55 +0000 (09:59 -0400)
rust-version
src/eval.rs
src/helpers.rs
src/machine.rs
src/shims/backtrace.rs
src/shims/env.rs
src/shims/foreign_items.rs
src/shims/os_str.rs
src/shims/posix/foreign_items.rs
src/shims/posix/thread.rs
src/shims/windows/foreign_items.rs

index 9890818ee952b193355469b3447f76ba36beb5fd..23819ebc24e42c243183757d4394435ce7e17360 100644 (file)
@@ -1 +1 @@
-46ae6ee65df19c6a3fb683499c1203e749975e60
+39e20f1ae5f13451eb35247808d6a2527cb7d060
index 95cdcb1b5a5987bd0cb34e9e8e341ce0594ece7a..f728248c3a723d649c4bd186d788b3e7186ead61 100644 (file)
@@ -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,
index d53b2969fb55ec86dae87f401fe0fc950e80e8ec..a6e66c3dbd38ed193bec937c0ca3740775f7ca62 100644 (file)
@@ -440,7 +440,7 @@ fn last_error_place(&mut self) -> InterpResult<'tcx, MPlaceTy<'tcx, Tag>> {
         } 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)
index 7ec510d0506f2c52dded2af99828746e48ea8b0b..999e21796d3049f0d2b44012fca2a7932a2f3655 100644 (file)
@@ -199,7 +199,7 @@ pub fn init_extern_statics<'tcx, 'mir>(
                 // "__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 @@ pub fn init_extern_statics<'tcx, 'mir>(
                 // "_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
index 4ea374344c0dd1ec392dbcd583e85cd2a1cafa21..ec29fef6368fb94a402fe519fa3cc6daaddc9b79 100644 (file)
@@ -57,7 +57,8 @@ fn handle_miri_get_backtrace(
         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)?;
index 0c42daa2446a0b942c6e2a9b3fdb219ab79a8bab..d99ffb31b5cf5ee8ba68ab5879e7af91b7c15d30 100644 (file)
@@ -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 @@ fn GetEnvironmentStringsW(&mut self) -> InterpResult<'tcx, Scalar<Tag>> {
         }
         // 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 @@ fn update_environ(&mut self) -> InterpResult<'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 @@ fn update_environ(&mut self) -> InterpResult<'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())?;
index 5b241a2fb3c12146bfa8f112c661290c3fe1d442..5d46f3c05c3396f791053e3e0b5fc96af9e6417f 100644 (file)
@@ -67,18 +67,23 @@ fn prev_power_of_two(x: u64) -> u64 {
         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 @@ fn realloc(
                 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 @@ fn emulate_foreign_item_by_name(
             "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 @@ fn emulate_foreign_item_by_name(
                 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 @@ fn emulate_foreign_item_by_name(
                     Size::from_bytes(size),
                     Align::from_bytes(align).unwrap(),
                     MiriMemoryKind::Rust.into(),
-                );
+                )?;
                 this.write_scalar(ptr, dest)?;
             }
             "__rust_alloc_zeroed" => {
@@ -380,7 +385,7 @@ fn emulate_foreign_item_by_name(
                     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)?;
index 8a3f5677706ec04b922baa91f7fe44f7995c62e1..ea99921c0b67648b3628b757547c61422cf8bdc1 100644 (file)
@@ -161,14 +161,14 @@ fn alloc_os_str_as_c_str(
         &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 @@ fn alloc_os_str_as_wide_str(
         &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.
index 4035deff63ef048e8e7d01563fc0414c1401ec74..1cfc3f0a4e79f4803d1c566da8039a5a8cb2abc4 100644 (file)
@@ -159,7 +159,7 @@ fn emulate_foreign_item_by_name(
                         Size::from_bytes(size),
                         Align::from_bytes(align).unwrap(),
                         MiriMemoryKind::C.into(),
-                    );
+                    )?;
                     this.write_scalar(ptr, &ret.into())?;
                 }
                 this.write_null(dest)?;
index 1e4597848914bcd7c416dd94b4fbbdafbbe27150..ce1c817cf3ba003fc479f5f2ee15ca730965639a 100644 (file)
@@ -47,7 +47,7 @@ fn pthread_create(
         // 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,
index 1921af359423917fe9fc2561575f1f8df2f4ce1f..b5324576273c9204cb4acfa0747434c0228d0779 100644 (file)
@@ -115,7 +115,7 @@ fn emulate_foreign_item_by_name(
                 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" => {