From 67f6ac412d7b16e93cdce9ae7d5bb7d1f721e27e Mon Sep 17 00:00:00 2001 From: Christian Poveda Date: Wed, 12 Jun 2019 12:49:46 -0500 Subject: [PATCH 1/3] Add force_bits and force_ptr methods --- src/librustc_mir/interpret/eval_context.rs | 13 +++++++++++++ src/librustc_mir/interpret/machine.rs | 17 ++++++++++++++++- src/librustc_mir/interpret/memory.rs | 17 +++++++++++++++++ 3 files changed, 46 insertions(+), 1 deletion(-) diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index a34889e6f33bc..793759c2465a0 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -773,4 +773,17 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tc pub fn truncate(&self, value: u128, ty: TyLayout<'_>) -> u128 { truncate(value, ty.size) } + + #[inline(always)] + pub fn force_ptr( + &self, + scalar: Scalar, + ) -> InterpResult<'tcx, Pointer> { + self.memory.force_ptr(scalar) + } + + #[inline(always)] + pub fn force_bits(&self, scalar: Scalar) -> InterpResult<'tcx, u128> { + self.memory.force_bits(scalar) + } } diff --git a/src/librustc_mir/interpret/machine.rs b/src/librustc_mir/interpret/machine.rs index 7ee77a9a05f8b..989512e9f207e 100644 --- a/src/librustc_mir/interpret/machine.rs +++ b/src/librustc_mir/interpret/machine.rs @@ -11,7 +11,8 @@ use rustc::ty::{self, query::TyCtxtAt}; use super::{ Allocation, AllocId, InterpResult, Scalar, AllocationExtra, - InterpretCx, PlaceTy, OpTy, ImmTy, MemoryKind, + InterpretCx, PlaceTy, OpTy, ImmTy, MemoryKind, Pointer, + InterpErrorInfo, InterpError }; /// Whether this kind of memory is allowed to leak @@ -210,4 +211,18 @@ pub trait Machine<'a, 'mir, 'tcx>: Sized { ecx: &mut InterpretCx<'a, 'mir, 'tcx, Self>, extra: Self::FrameExtra, ) -> InterpResult<'tcx>; + + fn int_to_ptr( + _int: u64, + _extra: &Self::MemoryExtra, + ) -> InterpResult<'tcx, Pointer> { + Err(InterpErrorInfo::from(InterpError::ReadBytesAsPointer)) + } + + fn ptr_to_int( + _ptr: Pointer, + _extra: &Self::MemoryExtra, + ) -> InterpResult<'tcx, u64> { + Err(InterpErrorInfo::from(InterpError::ReadPointerAsBytes)) + } } diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs index 7126cd86a1959..4967d8c209d68 100644 --- a/src/librustc_mir/interpret/memory.rs +++ b/src/librustc_mir/interpret/memory.rs @@ -879,4 +879,21 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> { } Ok(()) } + + pub fn force_ptr( + &self, + scalar: Scalar, + ) -> InterpResult<'tcx, Pointer> { + match scalar { + Scalar::Ptr(ptr) => Ok(ptr), + _ => M::int_to_ptr(scalar.to_usize(self)?, &self.extra) + } + } + + pub fn force_bits(&self, scalar: Scalar) -> InterpResult<'tcx, u128> { + match scalar.to_bits_or_ptr(self.pointer_size(), self) { + Ok(bits) => Ok(bits), + Err(ptr) => Ok(M::ptr_to_int(ptr, &self.extra)? as u128) + } + } } From 666bebcdd9180f2e0a9c4c142a5f09f8d5f2cd64 Mon Sep 17 00:00:00 2001 From: Christian Poveda Date: Wed, 12 Jun 2019 13:08:09 -0500 Subject: [PATCH 2/3] Change to_ptr by force_ptr --- src/librustc_mir/interpret/memory.rs | 6 +++--- src/librustc_mir/interpret/operand.rs | 2 +- src/librustc_mir/interpret/place.rs | 2 +- src/librustc_mir/interpret/terminator.rs | 2 +- src/librustc_mir/interpret/validity.rs | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs index 4967d8c209d68..6dd0c9f7319b3 100644 --- a/src/librustc_mir/interpret/memory.rs +++ b/src/librustc_mir/interpret/memory.rs @@ -632,7 +632,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> { if size.bytes() == 0 { Ok(&[]) } else { - let ptr = ptr.to_ptr()?; + let ptr = self.force_ptr(ptr)?; self.get(ptr.alloc_id)?.get_bytes(self, ptr, size) } } @@ -719,8 +719,8 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> { // non-NULLness which already happened. return Ok(()); } - let src = src.to_ptr()?; - let dest = dest.to_ptr()?; + let src = self.force_ptr(src)?; + let dest = self.force_ptr(dest)?; // first copy the relocations to a temporary buffer, because // `get_bytes_mut` will clear the relocations, which is correct, diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs index 7c83bf1d27d94..a7ae737433e06 100644 --- a/src/librustc_mir/interpret/operand.rs +++ b/src/librustc_mir/interpret/operand.rs @@ -232,7 +232,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tcx, M> } // check for integer pointers before alignment to report better errors - let ptr = ptr.to_ptr()?; + let ptr = self.force_ptr(ptr)?; self.memory.check_align(ptr.into(), ptr_align)?; match mplace.layout.abi { layout::Abi::Scalar(..) => { diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs index 758230e2b7dcb..e05ed0906bab0 100644 --- a/src/librustc_mir/interpret/place.rs +++ b/src/librustc_mir/interpret/place.rs @@ -750,7 +750,7 @@ where } // check for integer pointers before alignment to report better errors - let ptr = ptr.to_ptr()?; + let ptr = self.force_ptr(ptr)?; self.memory.check_align(ptr.into(), ptr_align)?; let tcx = &*self.tcx; // FIXME: We should check that there are dest.layout.size many bytes available in diff --git a/src/librustc_mir/interpret/terminator.rs b/src/librustc_mir/interpret/terminator.rs index ff8d6804febbd..8579e221db3d2 100644 --- a/src/librustc_mir/interpret/terminator.rs +++ b/src/librustc_mir/interpret/terminator.rs @@ -79,7 +79,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tcx, M> let (fn_def, abi) = match func.layout.ty.sty { ty::FnPtr(sig) => { let caller_abi = sig.abi(); - let fn_ptr = self.read_scalar(func)?.to_ptr()?; + let fn_ptr = self.force_ptr(self.read_scalar(func)?.not_undef()?)?; let instance = self.memory.get_fn(fn_ptr)?; (instance, caller_abi) } diff --git a/src/librustc_mir/interpret/validity.rs b/src/librustc_mir/interpret/validity.rs index 6768d9ec6bc19..b4b7e72ad749f 100644 --- a/src/librustc_mir/interpret/validity.rs +++ b/src/librustc_mir/interpret/validity.rs @@ -559,7 +559,7 @@ impl<'rt, 'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> // This is the size in bytes of the whole array. let size = ty_size * len; - let ptr = mplace.ptr.to_ptr()?; + let ptr = self.ecx.force_ptr(mplace.ptr)?; // NOTE: Keep this in sync with the handling of integer and float // types above, in `visit_primitive`. From 212f233b7d548c54ddec73142dfce1ee96a0c5c9 Mon Sep 17 00:00:00 2001 From: Christian Poveda Date: Thu, 13 Jun 2019 12:26:10 -0500 Subject: [PATCH 3/3] Replace to_bits by force_bits and move size as parameter --- src/librustc_mir/interpret/eval_context.rs | 8 ++++++-- src/librustc_mir/interpret/memory.rs | 8 ++++++-- src/librustc_mir/interpret/operator.rs | 2 +- src/librustc_mir/interpret/place.rs | 2 +- 4 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index 793759c2465a0..17a39988217de 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -783,7 +783,11 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tc } #[inline(always)] - pub fn force_bits(&self, scalar: Scalar) -> InterpResult<'tcx, u128> { - self.memory.force_bits(scalar) + pub fn force_bits( + &self, + scalar: Scalar, + size: Size + ) -> InterpResult<'tcx, u128> { + self.memory.force_bits(scalar, size) } } diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs index 6dd0c9f7319b3..3922793a27c60 100644 --- a/src/librustc_mir/interpret/memory.rs +++ b/src/librustc_mir/interpret/memory.rs @@ -890,8 +890,12 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> { } } - pub fn force_bits(&self, scalar: Scalar) -> InterpResult<'tcx, u128> { - match scalar.to_bits_or_ptr(self.pointer_size(), self) { + pub fn force_bits( + &self, + scalar: Scalar, + size: Size + ) -> InterpResult<'tcx, u128> { + match scalar.to_bits_or_ptr(size, self) { Ok(bits) => Ok(bits), Err(ptr) => Ok(M::ptr_to_int(ptr, &self.extra)? as u128) } diff --git a/src/librustc_mir/interpret/operator.rs b/src/librustc_mir/interpret/operator.rs index db7da9359de7b..c6801efa9c4c8 100644 --- a/src/librustc_mir/interpret/operator.rs +++ b/src/librustc_mir/interpret/operator.rs @@ -347,7 +347,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tcx, M> } _ => { assert!(layout.ty.is_integral()); - let val = val.to_bits(layout.size)?; + let val = self.force_bits(val, layout.size)?; let res = match un_op { Not => !val, Neg => { diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs index e05ed0906bab0..6582d70339bfd 100644 --- a/src/librustc_mir/interpret/place.rs +++ b/src/librustc_mir/interpret/place.rs @@ -470,7 +470,7 @@ where let layout = self.layout_of(self.tcx.types.usize)?; let n = self.access_local(self.frame(), local, Some(layout))?; let n = self.read_scalar(n)?; - let n = n.to_bits(self.tcx.data_layout.pointer_size)?; + let n = self.force_bits(n.not_undef()?, self.tcx.data_layout.pointer_size)?; self.mplace_field(base, u64::try_from(n).unwrap())? }