diff --git a/src/helpers.rs b/src/helpers.rs index a26f12cdfb..fa03f1923f 100644 --- a/src/helpers.rs +++ b/src/helpers.rs @@ -1312,3 +1312,15 @@ pub(crate) fn windows_check_buffer_size((success, len): (bool, u64)) -> u32 { u32::try_from(len).unwrap() } } + +pub(crate) fn get_arg<'tcx>( + ecx: &mut MiriInterpCx<'tcx>, + op: &OpTy<'tcx>, + ty: Ty<'tcx>, +) -> InterpResult<'tcx, OpTy<'tcx>> { + let ty_layout = ecx.layout_of(ty)?; + if !op.layout.backend_repr.eq_up_to_validity(&ty_layout.backend_repr) { + throw_ub_format!("Invalid argument type: ABI mismatch"); + } + op.transmute(ty_layout, ecx) +} diff --git a/src/shims/x86/sse42.rs b/src/shims/x86/sse42.rs index 02336a722f..4ac5669eb2 100644 --- a/src/shims/x86/sse42.rs +++ b/src/shims/x86/sse42.rs @@ -5,6 +5,7 @@ use rustc_middle::ty::layout::LayoutOf as _; use rustc_span::Symbol; use rustc_target::callconv::{Conv, FnAbi}; +use crate::helpers::get_arg; use crate::*; /// A bitmask constant for scrutinizing the immediate byte provided @@ -204,11 +205,11 @@ fn deconstruct_args<'tcx>( abi: &FnAbi<'tcx, Ty<'tcx>>, args: &[OpTy<'tcx>], ) -> InterpResult<'tcx, (OpTy<'tcx>, OpTy<'tcx>, Option<(u64, u64)>, u8)> { - let array_layout_fn = |ecx: &mut MiriInterpCx<'tcx>, imm: u8| { + let array_ty_fn = |ecx: &mut MiriInterpCx<'tcx>, imm: u8| { if imm & USE_WORDS != 0 { - ecx.layout_of(Ty::new_array(ecx.tcx.tcx, ecx.tcx.types.u16, 8)) + Ty::new_array(ecx.tcx.tcx, ecx.tcx.types.u16, 8) } else { - ecx.layout_of(Ty::new_array(ecx.tcx.tcx, ecx.tcx.types.u8, 16)) + Ty::new_array(ecx.tcx.tcx, ecx.tcx.types.u8, 16) } }; @@ -230,18 +231,18 @@ fn deconstruct_args<'tcx>( let len1 = u64::from(ecx.read_scalar(len1)?.to_u32()?.min(default_len)); let len2 = u64::from(ecx.read_scalar(len2)?.to_u32()?.min(default_len)); - let array_layout = array_layout_fn(ecx, imm)?; - let str1 = str1.transmute(array_layout, ecx)?; - let str2 = str2.transmute(array_layout, ecx)?; + let array_ty = array_ty_fn(ecx, imm); + let str1 = get_arg(ecx, str1, array_ty)?; + let str2 = get_arg(ecx, str2, array_ty)?; interp_ok((str1, str2, Some((len1, len2)), imm)) } else { let [str1, str2, imm] = ecx.check_shim(abi, Conv::C, link_name, args)?; let imm = ecx.read_scalar(imm)?.to_u8()?; - let array_layout = array_layout_fn(ecx, imm)?; - let str1 = str1.transmute(array_layout, ecx)?; - let str2 = str2.transmute(array_layout, ecx)?; + let array_ty = array_ty_fn(ecx, imm); + let str1 = get_arg(ecx, str1, array_ty)?; + let str2 = get_arg(ecx, str2, array_ty)?; interp_ok((str1, str2, None, imm)) }