X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Fhelpers.rs;h=7f99aa1997068ae3099f0d01112423af4b71e488;hb=879000b133aed8cc1893c84eb5319b491a4756d9;hp=7215cb4b0c7bde4cca000e9350e98bb3254231e1;hpb=4e231bab5ef620073c3c29b9b1f507f4a8f8c448;p=rust.git diff --git a/src/helpers.rs b/src/helpers.rs index 7215cb4b0c7..7f99aa19970 100644 --- a/src/helpers.rs +++ b/src/helpers.rs @@ -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 { - 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(), @@ -566,6 +566,74 @@ fn read_timespec( Duration::new(seconds, nanoseconds) }) } + + fn read_c_str<'a>(&'a self, sptr: Scalar) -> InterpResult<'tcx, &'a [u8]> + where + 'tcx: 'a, + 'mir: 'a, + { + let this = self.eval_context_ref(); + let size1 = Size::from_bytes(1); + 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 mut len = Size::ZERO; + loop { + // 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 { + len = len + size1; + } + } + + // Step 2: get the bytes. + this.memory.read_bytes(ptr.into(), len) + } + + fn read_wide_str(&self, sptr: Scalar) -> InterpResult<'tcx, Vec> { + 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(); + loop { + // 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 { + wchars.push(wchar); + ptr = ptr.offset(size2, this)?; + } + } + + 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. @@ -581,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",