]> git.lizzy.rs Git - rust.git/blobdiff - src/helpers.rs
Detect `std` by checking if the crate defines `#[lang = "start"]` rather than string...
[rust.git] / src / helpers.rs
index ef5ea9447808cb344d3107d40fde0d057c974f64..7f99aa1997068ae3099f0d01112423af4b71e488 100644 (file)
@@ -8,7 +8,7 @@
 use rustc_hir::def_id::{DefId, CRATE_DEF_INDEX};
 use rustc_middle::mir;
 use rustc_middle::ty::{self, layout::TyAndLayout, List, TyCtxt};
-use rustc_target::abi::{FieldsShape, LayoutOf, Size, Variants};
+use rustc_target::abi::{Align, FieldsShape, LayoutOf, Size, Variants};
 use rustc_target::spec::abi::Abi;
 
 use rand::RngCore;
@@ -19,7 +19,7 @@ impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mi
 
 /// Gets an instance for a path.
 fn try_resolve_did<'mir, 'tcx>(tcx: TyCtxt<'tcx>, path: &[&str]) -> Option<DefId> {
-    tcx.crates().iter().find(|&&krate| tcx.original_crate_name(krate).as_str() == path[0]).and_then(
+    tcx.crates().iter().find(|&&krate| tcx.crate_name(krate).as_str() == path[0]).and_then(
         |krate| {
             let krate = DefId { krate: *krate, index: CRATE_DEF_INDEX };
             let mut items = tcx.item_children(krate);
@@ -165,7 +165,7 @@ fn call_function(
         let this = self.eval_context_mut();
         let param_env = ty::ParamEnv::reveal_all(); // in Miri this is always the param_env we use... and this.param_env is private.
         let callee_abi = f.ty(*this.tcx, param_env).fn_sig(*this.tcx).abi();
-        if callee_abi != caller_abi {
+        if this.machine.enforce_abi && callee_abi != caller_abi {
             throw_ub_format!(
                 "calling a function with ABI {} using caller ABI {}",
                 callee_abi.name(),
@@ -577,10 +577,12 @@ fn read_c_str<'a>(&'a self, sptr: Scalar<Tag>) -> InterpResult<'tcx, &'a [u8]>
         let ptr = this.force_ptr(sptr)?; // We need to read at least 1 byte, so we can eagerly get a ptr.
 
         // Step 1: determine the length.
-        let alloc = this.memory.get_raw(ptr.alloc_id)?;
         let mut len = Size::ZERO;
         loop {
-            let byte = alloc.read_scalar(this, ptr.offset(len, this)?, size1)?.to_u8()?;
+            // FIXME: We are re-getting the allocation each time around the loop.
+            // Would be nice if we could somehow "extend" an existing AllocRange.
+            let alloc = this.memory.get(ptr.offset(len, this)?.into(), size1, Align::ONE)?.unwrap(); // not a ZST, so we will get a result
+            let byte = alloc.read_scalar(alloc_range(Size::ZERO, size1))?.to_u8()?;
             if byte == 0 {
                 break;
             } else {
@@ -595,12 +597,15 @@ fn read_c_str<'a>(&'a self, sptr: Scalar<Tag>) -> InterpResult<'tcx, &'a [u8]>
     fn read_wide_str(&self, sptr: Scalar<Tag>) -> InterpResult<'tcx, Vec<u16>> {
         let this = self.eval_context_ref();
         let size2 = Size::from_bytes(2);
+        let align2 = Align::from_bytes(2).unwrap();
 
         let mut ptr = this.force_ptr(sptr)?; // We need to read at least 1 wchar, so we can eagerly get a ptr.
         let mut wchars = Vec::new();
-        let alloc = this.memory.get_raw(ptr.alloc_id)?;
         loop {
-            let wchar = alloc.read_scalar(this, ptr, size2)?.to_u16()?;
+            // FIXME: We are re-getting the allocation each time around the loop.
+            // Would be nice if we could somehow "extend" an existing AllocRange.
+            let alloc = this.memory.get(ptr.into(), size2, align2)?.unwrap(); // not a ZST, so we will get a result
+            let wchar = alloc.read_scalar(alloc_range(Size::ZERO, size2))?.to_u16()?;
             if wchar == 0 {
                 break;
             } else {
@@ -611,6 +616,24 @@ fn read_wide_str(&self, sptr: Scalar<Tag>) -> InterpResult<'tcx, Vec<u16>> {
 
         Ok(wchars)
     }
+
+    /// Check that the ABI is what we expect.
+    fn check_abi<'a>(&self, abi: Abi, exp_abi: Abi) -> InterpResult<'a, ()> {
+        if self.eval_context_ref().machine.enforce_abi && abi != exp_abi {
+            throw_ub_format!(
+                "calling a function with ABI {} using caller ABI {}",
+                exp_abi.name(),
+                abi.name()
+            )
+        }
+        Ok(())
+    }
+
+    fn in_std(&self) -> bool {
+        let this = self.eval_context_ref();
+        this.tcx.def_path(this.frame().instance.def_id()).krate
+            == this.tcx.def_path(this.tcx.lang_items().start_fn().unwrap()).krate
+    }
 }
 
 /// Check that the number of args is what we expect.
@@ -626,19 +649,6 @@ pub fn check_arg_count<'a, 'tcx, const N: usize>(
     throw_ub_format!("incorrect number of arguments: got {}, expected {}", args.len(), N)
 }
 
-/// Check that the ABI is what we expect.
-pub fn check_abi<'a>(abi: Abi, exp_abi: Abi) -> InterpResult<'a, ()> {
-    if abi == exp_abi {
-        Ok(())
-    } else {
-        throw_ub_format!(
-            "calling a function with ABI {} using caller ABI {}",
-            exp_abi.name(),
-            abi.name()
-        )
-    }
-}
-
 pub fn isolation_error(name: &str) -> InterpResult<'static> {
     throw_machine_stop!(TerminationInfo::UnsupportedInIsolation(format!(
         "{} not available when isolation is enabled",