rename deref_operand → deref_pointer and some Miri helper functions
This commit is contained in:
parent
866710c552
commit
7d5886504c
25 changed files with 84 additions and 85 deletions
|
@ -214,9 +214,9 @@ impl<'mir, 'tcx: 'mir> CompileTimeEvalContext<'mir, 'tcx> {
|
||||||
// &str or &&str
|
// &str or &&str
|
||||||
assert!(args.len() == 1);
|
assert!(args.len() == 1);
|
||||||
|
|
||||||
let mut msg_place = self.deref_operand(&args[0])?;
|
let mut msg_place = self.deref_pointer(&args[0])?;
|
||||||
while msg_place.layout.ty.is_ref() {
|
while msg_place.layout.ty.is_ref() {
|
||||||
msg_place = self.deref_operand(&msg_place)?;
|
msg_place = self.deref_pointer(&msg_place)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let msg = Symbol::intern(self.read_str(&msg_place)?);
|
let msg = Symbol::intern(self.read_str(&msg_place)?);
|
||||||
|
|
|
@ -102,7 +102,7 @@ pub(crate) fn const_to_valtree_inner<'tcx>(
|
||||||
ty::FnPtr(_) | ty::RawPtr(_) => Err(ValTreeCreationError::NonSupportedType),
|
ty::FnPtr(_) | ty::RawPtr(_) => Err(ValTreeCreationError::NonSupportedType),
|
||||||
|
|
||||||
ty::Ref(_, _, _) => {
|
ty::Ref(_, _, _) => {
|
||||||
let Ok(derefd_place)= ecx.deref_operand(place) else {
|
let Ok(derefd_place)= ecx.deref_pointer(place) else {
|
||||||
return Err(ValTreeCreationError::Other);
|
return Err(ValTreeCreationError::Other);
|
||||||
};
|
};
|
||||||
debug!(?derefd_place);
|
debug!(?derefd_place);
|
||||||
|
|
|
@ -144,7 +144,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
}
|
}
|
||||||
|
|
||||||
sym::min_align_of_val | sym::size_of_val => {
|
sym::min_align_of_val | sym::size_of_val => {
|
||||||
// Avoid `deref_operand` -- this is not a deref, the ptr does not have to be
|
// Avoid `deref_pointer` -- this is not a deref, the ptr does not have to be
|
||||||
// dereferenceable!
|
// dereferenceable!
|
||||||
let place = self.ref_to_mplace(&self.read_immediate(&args[0])?)?;
|
let place = self.ref_to_mplace(&self.read_immediate(&args[0])?)?;
|
||||||
let (size, align) = self
|
let (size, align) = self
|
||||||
|
@ -225,7 +225,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
self.write_scalar(val, dest)?;
|
self.write_scalar(val, dest)?;
|
||||||
}
|
}
|
||||||
sym::discriminant_value => {
|
sym::discriminant_value => {
|
||||||
let place = self.deref_operand(&args[0])?;
|
let place = self.deref_pointer(&args[0])?;
|
||||||
let variant = self.read_discriminant(&place)?;
|
let variant = self.read_discriminant(&place)?;
|
||||||
let discr = self.discriminant_for_variant(place.layout, variant)?;
|
let discr = self.discriminant_for_variant(place.layout, variant)?;
|
||||||
self.write_scalar(discr, dest)?;
|
self.write_scalar(discr, dest)?;
|
||||||
|
|
|
@ -419,7 +419,7 @@ where
|
||||||
///
|
///
|
||||||
/// Only call this if you are sure the place is "valid" (aligned and inbounds), or do not
|
/// Only call this if you are sure the place is "valid" (aligned and inbounds), or do not
|
||||||
/// want to ever use the place for memory access!
|
/// want to ever use the place for memory access!
|
||||||
/// Generally prefer `deref_operand`.
|
/// Generally prefer `deref_pointer`.
|
||||||
pub fn ref_to_mplace(
|
pub fn ref_to_mplace(
|
||||||
&self,
|
&self,
|
||||||
val: &ImmTy<'tcx, M::Provenance>,
|
val: &ImmTy<'tcx, M::Provenance>,
|
||||||
|
@ -439,8 +439,9 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Take an operand, representing a pointer, and dereference it to a place.
|
/// Take an operand, representing a pointer, and dereference it to a place.
|
||||||
|
/// Corresponds to the `*` operator in Rust.
|
||||||
#[instrument(skip(self), level = "debug")]
|
#[instrument(skip(self), level = "debug")]
|
||||||
pub fn deref_operand(
|
pub fn deref_pointer(
|
||||||
&self,
|
&self,
|
||||||
src: &impl Readable<'tcx, M::Provenance>,
|
src: &impl Readable<'tcx, M::Provenance>,
|
||||||
) -> InterpResult<'tcx, MPlaceTy<'tcx, M::Provenance>> {
|
) -> InterpResult<'tcx, MPlaceTy<'tcx, M::Provenance>> {
|
||||||
|
|
|
@ -290,7 +290,7 @@ where
|
||||||
OpaqueCast(ty) => base.transmute(self.layout_of(ty)?, self)?,
|
OpaqueCast(ty) => base.transmute(self.layout_of(ty)?, self)?,
|
||||||
Field(field, _) => self.project_field(base, field.index())?,
|
Field(field, _) => self.project_field(base, field.index())?,
|
||||||
Downcast(_, variant) => self.project_downcast(base, variant)?,
|
Downcast(_, variant) => self.project_downcast(base, variant)?,
|
||||||
Deref => self.deref_operand(&base.to_op(self)?)?.into(),
|
Deref => self.deref_pointer(&base.to_op(self)?)?.into(),
|
||||||
Index(local) => {
|
Index(local) => {
|
||||||
let layout = self.layout_of(self.tcx.types.usize)?;
|
let layout = self.layout_of(self.tcx.types.usize)?;
|
||||||
let n = self.local_to_op(self.frame(), local, Some(layout))?;
|
let n = self.local_to_op(self.frame(), local, Some(layout))?;
|
||||||
|
|
|
@ -661,7 +661,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
let receiver_place = loop {
|
let receiver_place = loop {
|
||||||
match receiver.layout.ty.kind() {
|
match receiver.layout.ty.kind() {
|
||||||
ty::Ref(..) | ty::RawPtr(..) => {
|
ty::Ref(..) | ty::RawPtr(..) => {
|
||||||
// We do *not* use `deref_operand` here: we don't want to conceptually
|
// We do *not* use `deref_pointer` here: we don't want to conceptually
|
||||||
// create a place that must be dereferenceable, since the receiver might
|
// create a place that must be dereferenceable, since the receiver might
|
||||||
// be a raw pointer and (for `*const dyn Trait`) we don't need to
|
// be a raw pointer and (for `*const dyn Trait`) we don't need to
|
||||||
// actually access memory to resolve this method.
|
// actually access memory to resolve this method.
|
||||||
|
|
|
@ -345,6 +345,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
|
||||||
value: &OpTy<'tcx, M::Provenance>,
|
value: &OpTy<'tcx, M::Provenance>,
|
||||||
ptr_kind: PointerKind,
|
ptr_kind: PointerKind,
|
||||||
) -> InterpResult<'tcx> {
|
) -> InterpResult<'tcx> {
|
||||||
|
// Not using `deref_pointer` since we do the dereferenceable check ourselves below.
|
||||||
let place = self.ecx.ref_to_mplace(&self.read_immediate(value, ptr_kind.into())?)?;
|
let place = self.ecx.ref_to_mplace(&self.read_immediate(value, ptr_kind.into())?)?;
|
||||||
// Handle wide pointers.
|
// Handle wide pointers.
|
||||||
// Check metadata early, for better diagnostics
|
// Check metadata early, for better diagnostics
|
||||||
|
@ -515,9 +516,6 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
|
||||||
Ok(true)
|
Ok(true)
|
||||||
}
|
}
|
||||||
ty::RawPtr(..) => {
|
ty::RawPtr(..) => {
|
||||||
// We are conservative with uninit for integers, but try to
|
|
||||||
// actually enforce the strict rules for raw pointers (mostly because
|
|
||||||
// that lets us re-use `ref_to_mplace`).
|
|
||||||
let place =
|
let place =
|
||||||
self.ecx.ref_to_mplace(&self.read_immediate(value, ExpectedKind::RawPtr)?)?;
|
self.ecx.ref_to_mplace(&self.read_immediate(value, ExpectedKind::RawPtr)?)?;
|
||||||
if place.layout.is_unsized() {
|
if place.layout.is_unsized() {
|
||||||
|
|
|
@ -206,7 +206,7 @@ pub(super) trait EvalContextExtPriv<'mir, 'tcx: 'mir>:
|
||||||
) -> InterpResult<'tcx, Option<Id>> {
|
) -> InterpResult<'tcx, Option<Id>> {
|
||||||
let this = self.eval_context_mut();
|
let this = self.eval_context_mut();
|
||||||
let value_place =
|
let value_place =
|
||||||
this.deref_operand_and_offset(lock_op, offset, lock_layout, this.machine.layouts.u32)?;
|
this.deref_pointer_and_offset(lock_op, offset, lock_layout, this.machine.layouts.u32)?;
|
||||||
|
|
||||||
// Since we are lazy, this update has to be atomic.
|
// Since we are lazy, this update has to be atomic.
|
||||||
let (old, success) = this
|
let (old, success) = this
|
||||||
|
|
|
@ -715,9 +715,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Dereference a pointer operand to a place using `layout` instead of the pointer's declared type
|
/// Dereference a pointer operand to a place using `layout` instead of the pointer's declared type
|
||||||
fn deref_operand_as(
|
fn deref_pointer_as(
|
||||||
&self,
|
&self,
|
||||||
op: &OpTy<'tcx, Provenance>,
|
op: &impl Readable<'tcx, Provenance>,
|
||||||
layout: TyAndLayout<'tcx>,
|
layout: TyAndLayout<'tcx>,
|
||||||
) -> InterpResult<'tcx, MPlaceTy<'tcx, Provenance>> {
|
) -> InterpResult<'tcx, MPlaceTy<'tcx, Provenance>> {
|
||||||
let this = self.eval_context_ref();
|
let this = self.eval_context_ref();
|
||||||
|
@ -746,15 +746,15 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Calculates the MPlaceTy given the offset and layout of an access on an operand
|
/// Calculates the MPlaceTy given the offset and layout of an access on an operand
|
||||||
fn deref_operand_and_offset(
|
fn deref_pointer_and_offset(
|
||||||
&self,
|
&self,
|
||||||
op: &OpTy<'tcx, Provenance>,
|
op: &impl Readable<'tcx, Provenance>,
|
||||||
offset: u64,
|
offset: u64,
|
||||||
base_layout: TyAndLayout<'tcx>,
|
base_layout: TyAndLayout<'tcx>,
|
||||||
value_layout: TyAndLayout<'tcx>,
|
value_layout: TyAndLayout<'tcx>,
|
||||||
) -> InterpResult<'tcx, MPlaceTy<'tcx, Provenance>> {
|
) -> InterpResult<'tcx, MPlaceTy<'tcx, Provenance>> {
|
||||||
let this = self.eval_context_ref();
|
let this = self.eval_context_ref();
|
||||||
let op_place = this.deref_operand_as(op, base_layout)?;
|
let op_place = this.deref_pointer_as(op, base_layout)?;
|
||||||
let offset = Size::from_bytes(offset);
|
let offset = Size::from_bytes(offset);
|
||||||
|
|
||||||
// Ensure that the access is within bounds.
|
// Ensure that the access is within bounds.
|
||||||
|
@ -763,28 +763,28 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||||
Ok(value_place)
|
Ok(value_place)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_scalar_at_offset(
|
fn deref_pointer_and_read(
|
||||||
&self,
|
&self,
|
||||||
op: &OpTy<'tcx, Provenance>,
|
op: &impl Readable<'tcx, Provenance>,
|
||||||
offset: u64,
|
offset: u64,
|
||||||
base_layout: TyAndLayout<'tcx>,
|
base_layout: TyAndLayout<'tcx>,
|
||||||
value_layout: TyAndLayout<'tcx>,
|
value_layout: TyAndLayout<'tcx>,
|
||||||
) -> InterpResult<'tcx, Scalar<Provenance>> {
|
) -> InterpResult<'tcx, Scalar<Provenance>> {
|
||||||
let this = self.eval_context_ref();
|
let this = self.eval_context_ref();
|
||||||
let value_place = this.deref_operand_and_offset(op, offset, base_layout, value_layout)?;
|
let value_place = this.deref_pointer_and_offset(op, offset, base_layout, value_layout)?;
|
||||||
this.read_scalar(&value_place)
|
this.read_scalar(&value_place)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_scalar_at_offset(
|
fn deref_pointer_and_write(
|
||||||
&mut self,
|
&mut self,
|
||||||
op: &OpTy<'tcx, Provenance>,
|
op: &impl Readable<'tcx, Provenance>,
|
||||||
offset: u64,
|
offset: u64,
|
||||||
value: impl Into<Scalar<Provenance>>,
|
value: impl Into<Scalar<Provenance>>,
|
||||||
base_layout: TyAndLayout<'tcx>,
|
base_layout: TyAndLayout<'tcx>,
|
||||||
value_layout: TyAndLayout<'tcx>,
|
value_layout: TyAndLayout<'tcx>,
|
||||||
) -> InterpResult<'tcx, ()> {
|
) -> InterpResult<'tcx, ()> {
|
||||||
let this = self.eval_context_mut();
|
let this = self.eval_context_mut();
|
||||||
let value_place = this.deref_operand_and_offset(op, offset, base_layout, value_layout)?;
|
let value_place = this.deref_pointer_and_offset(op, offset, base_layout, value_layout)?;
|
||||||
this.write_scalar(value, &value_place)
|
this.write_scalar(value, &value_place)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -97,7 +97,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||||
1 => {
|
1 => {
|
||||||
let [_flags, buf] = this.check_shim(abi, Abi::Rust, link_name, args)?;
|
let [_flags, buf] = this.check_shim(abi, Abi::Rust, link_name, args)?;
|
||||||
|
|
||||||
let buf_place = this.deref_operand(buf)?;
|
let buf_place = this.deref_pointer(buf)?;
|
||||||
|
|
||||||
let ptr_layout = this.layout_of(ptr_ty)?;
|
let ptr_layout = this.layout_of(ptr_ty)?;
|
||||||
|
|
||||||
|
|
|
@ -418,9 +418,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||||
// // First thing: load all the arguments. Details depend on the shim.
|
// // First thing: load all the arguments. Details depend on the shim.
|
||||||
// let arg1 = this.read_scalar(arg1)?.to_u32()?;
|
// let arg1 = this.read_scalar(arg1)?.to_u32()?;
|
||||||
// let arg2 = this.read_pointer(arg2)?; // when you need to work with the pointer directly
|
// let arg2 = this.read_pointer(arg2)?; // when you need to work with the pointer directly
|
||||||
// let arg3 = this.deref_operand_as(arg3, this.libc_ty_layout("some_libc_struct"))?; // when you want to load/store
|
// let arg3 = this.deref_pointer_as(arg3, this.libc_ty_layout("some_libc_struct"))?; // when you want to load/store
|
||||||
// // through the pointer and supply the type information yourself
|
// // through the pointer and supply the type information yourself
|
||||||
// let arg4 = this.deref_operand(arg4)?; // when you want to load/store through the pointer and trust
|
// let arg4 = this.deref_pointer(arg4)?; // when you want to load/store through the pointer and trust
|
||||||
// // the user-given type (which you shouldn't usually do)
|
// // the user-given type (which you shouldn't usually do)
|
||||||
//
|
//
|
||||||
// // ...
|
// // ...
|
||||||
|
|
|
@ -130,7 +130,7 @@ trait EvalContextPrivExt<'mir, 'tcx: 'mir>: MiriInterpCxExt<'mir, 'tcx> {
|
||||||
let this = self.eval_context_mut();
|
let this = self.eval_context_mut();
|
||||||
|
|
||||||
let [place] = check_arg_count(args)?;
|
let [place] = check_arg_count(args)?;
|
||||||
let place = this.deref_operand(place)?;
|
let place = this.deref_pointer(place)?;
|
||||||
|
|
||||||
// Perform atomic load.
|
// Perform atomic load.
|
||||||
let val = this.read_scalar_atomic(&place, atomic)?;
|
let val = this.read_scalar_atomic(&place, atomic)?;
|
||||||
|
@ -147,7 +147,7 @@ trait EvalContextPrivExt<'mir, 'tcx: 'mir>: MiriInterpCxExt<'mir, 'tcx> {
|
||||||
let this = self.eval_context_mut();
|
let this = self.eval_context_mut();
|
||||||
|
|
||||||
let [place, val] = check_arg_count(args)?;
|
let [place, val] = check_arg_count(args)?;
|
||||||
let place = this.deref_operand(place)?;
|
let place = this.deref_pointer(place)?;
|
||||||
|
|
||||||
// Perform regular load.
|
// Perform regular load.
|
||||||
let val = this.read_scalar(val)?;
|
let val = this.read_scalar(val)?;
|
||||||
|
@ -188,7 +188,7 @@ trait EvalContextPrivExt<'mir, 'tcx: 'mir>: MiriInterpCxExt<'mir, 'tcx> {
|
||||||
let this = self.eval_context_mut();
|
let this = self.eval_context_mut();
|
||||||
|
|
||||||
let [place, rhs] = check_arg_count(args)?;
|
let [place, rhs] = check_arg_count(args)?;
|
||||||
let place = this.deref_operand(place)?;
|
let place = this.deref_pointer(place)?;
|
||||||
let rhs = this.read_immediate(rhs)?;
|
let rhs = this.read_immediate(rhs)?;
|
||||||
|
|
||||||
if !place.layout.ty.is_integral() && !place.layout.ty.is_unsafe_ptr() {
|
if !place.layout.ty.is_integral() && !place.layout.ty.is_unsafe_ptr() {
|
||||||
|
@ -229,7 +229,7 @@ trait EvalContextPrivExt<'mir, 'tcx: 'mir>: MiriInterpCxExt<'mir, 'tcx> {
|
||||||
let this = self.eval_context_mut();
|
let this = self.eval_context_mut();
|
||||||
|
|
||||||
let [place, new] = check_arg_count(args)?;
|
let [place, new] = check_arg_count(args)?;
|
||||||
let place = this.deref_operand(place)?;
|
let place = this.deref_pointer(place)?;
|
||||||
let new = this.read_scalar(new)?;
|
let new = this.read_scalar(new)?;
|
||||||
|
|
||||||
let old = this.atomic_exchange_scalar(&place, new, atomic)?;
|
let old = this.atomic_exchange_scalar(&place, new, atomic)?;
|
||||||
|
@ -248,7 +248,7 @@ trait EvalContextPrivExt<'mir, 'tcx: 'mir>: MiriInterpCxExt<'mir, 'tcx> {
|
||||||
let this = self.eval_context_mut();
|
let this = self.eval_context_mut();
|
||||||
|
|
||||||
let [place, expect_old, new] = check_arg_count(args)?;
|
let [place, expect_old, new] = check_arg_count(args)?;
|
||||||
let place = this.deref_operand(place)?;
|
let place = this.deref_pointer(place)?;
|
||||||
let expect_old = this.read_immediate(expect_old)?; // read as immediate for the sake of `binary_op()`
|
let expect_old = this.read_immediate(expect_old)?; // read as immediate for the sake of `binary_op()`
|
||||||
let new = this.read_scalar(new)?;
|
let new = this.read_scalar(new)?;
|
||||||
|
|
||||||
|
|
|
@ -96,12 +96,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||||
// Raw memory accesses
|
// Raw memory accesses
|
||||||
"volatile_load" => {
|
"volatile_load" => {
|
||||||
let [place] = check_arg_count(args)?;
|
let [place] = check_arg_count(args)?;
|
||||||
let place = this.deref_operand(place)?;
|
let place = this.deref_pointer(place)?;
|
||||||
this.copy_op(&place, dest, /*allow_transmute*/ false)?;
|
this.copy_op(&place, dest, /*allow_transmute*/ false)?;
|
||||||
}
|
}
|
||||||
"volatile_store" => {
|
"volatile_store" => {
|
||||||
let [place, dest] = check_arg_count(args)?;
|
let [place, dest] = check_arg_count(args)?;
|
||||||
let place = this.deref_operand(place)?;
|
let place = this.deref_pointer(place)?;
|
||||||
this.copy_op(dest, &place, /*allow_transmute*/ false)?;
|
this.copy_op(dest, &place, /*allow_transmute*/ false)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -534,7 +534,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||||
let dest = this.project_index(&dest, i)?;
|
let dest = this.project_index(&dest, i)?;
|
||||||
|
|
||||||
let val = if simd_element_to_bool(mask)? {
|
let val = if simd_element_to_bool(mask)? {
|
||||||
let place = this.deref_operand(&ptr)?;
|
let place = this.deref_pointer(&ptr)?;
|
||||||
this.read_immediate(&place)?
|
this.read_immediate(&place)?
|
||||||
} else {
|
} else {
|
||||||
passthru
|
passthru
|
||||||
|
@ -557,7 +557,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||||
let mask = this.read_immediate(&this.project_index(&mask, i)?)?;
|
let mask = this.read_immediate(&this.project_index(&mask, i)?)?;
|
||||||
|
|
||||||
if simd_element_to_bool(mask)? {
|
if simd_element_to_bool(mask)? {
|
||||||
let place = this.deref_operand(&ptr)?;
|
let place = this.deref_pointer(&ptr)?;
|
||||||
this.write_immediate(*value, &place)?;
|
this.write_immediate(*value, &place)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||||
this.assert_target_os_is_unix("clock_gettime");
|
this.assert_target_os_is_unix("clock_gettime");
|
||||||
|
|
||||||
let clk_id = this.read_scalar(clk_id_op)?.to_i32()?;
|
let clk_id = this.read_scalar(clk_id_op)?.to_i32()?;
|
||||||
let tp = this.deref_operand_as(tp_op, this.libc_ty_layout("timespec"))?;
|
let tp = this.deref_pointer_as(tp_op, this.libc_ty_layout("timespec"))?;
|
||||||
|
|
||||||
let absolute_clocks;
|
let absolute_clocks;
|
||||||
let mut relative_clocks;
|
let mut relative_clocks;
|
||||||
|
@ -92,7 +92,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||||
this.assert_target_os_is_unix("gettimeofday");
|
this.assert_target_os_is_unix("gettimeofday");
|
||||||
this.check_no_isolation("`gettimeofday`")?;
|
this.check_no_isolation("`gettimeofday`")?;
|
||||||
|
|
||||||
let tv = this.deref_operand_as(tv_op, this.libc_ty_layout("timeval"))?;
|
let tv = this.deref_pointer_as(tv_op, this.libc_ty_layout("timeval"))?;
|
||||||
|
|
||||||
// Using tz is obsolete and should always be null
|
// Using tz is obsolete and should always be null
|
||||||
let tz = this.read_pointer(tz_op)?;
|
let tz = this.read_pointer(tz_op)?;
|
||||||
|
@ -121,7 +121,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||||
this.assert_target_os("windows", "GetSystemTimeAsFileTime");
|
this.assert_target_os("windows", "GetSystemTimeAsFileTime");
|
||||||
this.check_no_isolation("`GetSystemTimeAsFileTime`")?;
|
this.check_no_isolation("`GetSystemTimeAsFileTime`")?;
|
||||||
|
|
||||||
let filetime = this.deref_operand_as(LPFILETIME_op, this.windows_ty_layout("FILETIME"))?;
|
let filetime = this.deref_pointer_as(LPFILETIME_op, this.windows_ty_layout("FILETIME"))?;
|
||||||
|
|
||||||
let NANOS_PER_SEC = this.eval_windows_u64("time", "NANOS_PER_SEC");
|
let NANOS_PER_SEC = this.eval_windows_u64("time", "NANOS_PER_SEC");
|
||||||
let INTERVALS_PER_SEC = this.eval_windows_u64("time", "INTERVALS_PER_SEC");
|
let INTERVALS_PER_SEC = this.eval_windows_u64("time", "INTERVALS_PER_SEC");
|
||||||
|
@ -156,7 +156,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||||
let qpc = i64::try_from(duration.as_nanos()).map_err(|_| {
|
let qpc = i64::try_from(duration.as_nanos()).map_err(|_| {
|
||||||
err_unsup_format!("programs running longer than 2^63 nanoseconds are not supported")
|
err_unsup_format!("programs running longer than 2^63 nanoseconds are not supported")
|
||||||
})?;
|
})?;
|
||||||
this.write_scalar(Scalar::from_i64(qpc), &this.deref_operand(lpPerformanceCount_op)?)?;
|
this.write_scalar(Scalar::from_i64(qpc), &this.deref_pointer(lpPerformanceCount_op)?)?;
|
||||||
Ok(Scalar::from_i32(-1)) // return non-zero on success
|
Ok(Scalar::from_i32(-1)) // return non-zero on success
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -176,7 +176,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||||
// and thus 10^9 counts per second.
|
// and thus 10^9 counts per second.
|
||||||
this.write_scalar(
|
this.write_scalar(
|
||||||
Scalar::from_i64(1_000_000_000),
|
Scalar::from_i64(1_000_000_000),
|
||||||
&this.deref_operand_as(lpFrequency_op, this.machine.layouts.u64)?,
|
&this.deref_pointer_as(lpFrequency_op, this.machine.layouts.u64)?,
|
||||||
)?;
|
)?;
|
||||||
Ok(Scalar::from_i32(-1)) // Return non-zero on success
|
Ok(Scalar::from_i32(-1)) // Return non-zero on success
|
||||||
}
|
}
|
||||||
|
@ -203,7 +203,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||||
|
|
||||||
this.assert_target_os("macos", "mach_timebase_info");
|
this.assert_target_os("macos", "mach_timebase_info");
|
||||||
|
|
||||||
let info = this.deref_operand_as(info_op, this.libc_ty_layout("mach_timebase_info"))?;
|
let info = this.deref_pointer_as(info_op, this.libc_ty_layout("mach_timebase_info"))?;
|
||||||
|
|
||||||
// Since our emulated ticks in `mach_absolute_time` *are* nanoseconds,
|
// Since our emulated ticks in `mach_absolute_time` *are* nanoseconds,
|
||||||
// no scaling needs to happen.
|
// no scaling needs to happen.
|
||||||
|
@ -222,7 +222,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||||
|
|
||||||
this.assert_target_os_is_unix("nanosleep");
|
this.assert_target_os_is_unix("nanosleep");
|
||||||
|
|
||||||
let req = this.deref_operand_as(req_op, this.libc_ty_layout("timespec"))?;
|
let req = this.deref_pointer_as(req_op, this.libc_ty_layout("timespec"))?;
|
||||||
|
|
||||||
let duration = match this.read_timespec(&req)? {
|
let duration = match this.read_timespec(&req)? {
|
||||||
Some(duration) => duration,
|
Some(duration) => duration,
|
||||||
|
|
|
@ -191,7 +191,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||||
// Allocation
|
// Allocation
|
||||||
"posix_memalign" => {
|
"posix_memalign" => {
|
||||||
let [ret, align, size] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
let [ret, align, size] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
||||||
let ret = this.deref_operand(ret)?;
|
let ret = this.deref_pointer(ret)?;
|
||||||
let align = this.read_target_usize(align)?;
|
let align = this.read_target_usize(align)?;
|
||||||
let size = this.read_target_usize(size)?;
|
let size = this.read_target_usize(size)?;
|
||||||
// Align must be power of 2, and also at least ptr-sized (POSIX rules).
|
// Align must be power of 2, and also at least ptr-sized (POSIX rules).
|
||||||
|
@ -271,7 +271,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||||
// Thread-local storage
|
// Thread-local storage
|
||||||
"pthread_key_create" => {
|
"pthread_key_create" => {
|
||||||
let [key, dtor] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
let [key, dtor] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
||||||
let key_place = this.deref_operand_as(key, this.libc_ty_layout("pthread_key_t"))?;
|
let key_place = this.deref_pointer_as(key, this.libc_ty_layout("pthread_key_t"))?;
|
||||||
let dtor = this.read_pointer(dtor)?;
|
let dtor = this.read_pointer(dtor)?;
|
||||||
|
|
||||||
// Extract the function type out of the signature (that seems easier than constructing it ourselves).
|
// Extract the function type out of the signature (that seems easier than constructing it ourselves).
|
||||||
|
@ -506,7 +506,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||||
"pthread_attr_getguardsize"
|
"pthread_attr_getguardsize"
|
||||||
if this.frame_in_std() => {
|
if this.frame_in_std() => {
|
||||||
let [_attr, guard_size] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
let [_attr, guard_size] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
||||||
let guard_size = this.deref_operand(guard_size)?;
|
let guard_size = this.deref_pointer(guard_size)?;
|
||||||
let guard_size_layout = this.libc_ty_layout("size_t");
|
let guard_size_layout = this.libc_ty_layout("size_t");
|
||||||
this.write_scalar(Scalar::from_uint(this.machine.page_size, guard_size_layout.size), &guard_size)?;
|
this.write_scalar(Scalar::from_uint(this.machine.page_size, guard_size_layout.size), &guard_size)?;
|
||||||
|
|
||||||
|
@ -532,9 +532,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||||
// Hence we can mostly ignore the input `attr_place`.
|
// Hence we can mostly ignore the input `attr_place`.
|
||||||
let [attr_place, addr_place, size_place] =
|
let [attr_place, addr_place, size_place] =
|
||||||
this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
||||||
let _attr_place = this.deref_operand_as(attr_place, this.libc_ty_layout("pthread_attr_t"))?;
|
let _attr_place = this.deref_pointer_as(attr_place, this.libc_ty_layout("pthread_attr_t"))?;
|
||||||
let addr_place = this.deref_operand(addr_place)?;
|
let addr_place = this.deref_pointer(addr_place)?;
|
||||||
let size_place = this.deref_operand(size_place)?;
|
let size_place = this.deref_pointer(size_place)?;
|
||||||
|
|
||||||
this.write_scalar(
|
this.write_scalar(
|
||||||
Scalar::from_uint(this.machine.stack_addr, this.pointer_size()),
|
Scalar::from_uint(this.machine.stack_addr, this.pointer_size()),
|
||||||
|
@ -575,10 +575,10 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||||
this.check_no_isolation("`getpwuid_r`")?;
|
this.check_no_isolation("`getpwuid_r`")?;
|
||||||
|
|
||||||
let uid = this.read_scalar(uid)?.to_u32()?;
|
let uid = this.read_scalar(uid)?.to_u32()?;
|
||||||
let pwd = this.deref_operand_as(pwd, this.libc_ty_layout("passwd"))?;
|
let pwd = this.deref_pointer_as(pwd, this.libc_ty_layout("passwd"))?;
|
||||||
let buf = this.read_pointer(buf)?;
|
let buf = this.read_pointer(buf)?;
|
||||||
let buflen = this.read_target_usize(buflen)?;
|
let buflen = this.read_target_usize(buflen)?;
|
||||||
let result = this.deref_operand(result)?;
|
let result = this.deref_pointer(result)?;
|
||||||
|
|
||||||
// Must be for "us".
|
// Must be for "us".
|
||||||
if uid != crate::shims::unix::UID {
|
if uid != crate::shims::unix::UID {
|
||||||
|
|
|
@ -344,7 +344,7 @@ trait EvalContextExtPrivate<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx
|
||||||
let (created_sec, created_nsec) = metadata.created.unwrap_or((0, 0));
|
let (created_sec, created_nsec) = metadata.created.unwrap_or((0, 0));
|
||||||
let (modified_sec, modified_nsec) = metadata.modified.unwrap_or((0, 0));
|
let (modified_sec, modified_nsec) = metadata.modified.unwrap_or((0, 0));
|
||||||
|
|
||||||
let buf = this.deref_operand_as(buf_op, this.libc_ty_layout("stat"))?;
|
let buf = this.deref_pointer_as(buf_op, this.libc_ty_layout("stat"))?;
|
||||||
|
|
||||||
this.write_int_fields_named(
|
this.write_int_fields_named(
|
||||||
&[
|
&[
|
||||||
|
@ -1014,7 +1014,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||||
return Ok(-1);
|
return Ok(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
let statxbuf = this.deref_operand_as(statxbuf_op, this.libc_ty_layout("statx"))?;
|
let statxbuf = this.deref_pointer_as(statxbuf_op, this.libc_ty_layout("statx"))?;
|
||||||
|
|
||||||
let path = this.read_path_from_c_str(pathname_ptr)?.into_owned();
|
let path = this.read_path_from_c_str(pathname_ptr)?.into_owned();
|
||||||
// See <https://github.com/rust-lang/rust/pull/79196> for a discussion of argument sizes.
|
// See <https://github.com/rust-lang/rust/pull/79196> for a discussion of argument sizes.
|
||||||
|
@ -1420,7 +1420,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||||
// pub d_name: [c_char; 1024],
|
// pub d_name: [c_char; 1024],
|
||||||
// }
|
// }
|
||||||
|
|
||||||
let entry_place = this.deref_operand_as(entry_op, this.libc_ty_layout("dirent"))?;
|
let entry_place = this.deref_pointer_as(entry_op, this.libc_ty_layout("dirent"))?;
|
||||||
let name_place = this.project_field(&entry_place, 5)?;
|
let name_place = this.project_field(&entry_place, 5)?;
|
||||||
|
|
||||||
let file_name = dir_entry.file_name(); // not a Path as there are no separators!
|
let file_name = dir_entry.file_name(); // not a Path as there are no separators!
|
||||||
|
@ -1456,14 +1456,14 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||||
&entry_place,
|
&entry_place,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let result_place = this.deref_operand(result_op)?;
|
let result_place = this.deref_pointer(result_op)?;
|
||||||
this.write_scalar(this.read_scalar(entry_op)?, &result_place)?;
|
this.write_scalar(this.read_scalar(entry_op)?, &result_place)?;
|
||||||
|
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
// end of stream: return 0, assign *result=NULL
|
// end of stream: return 0, assign *result=NULL
|
||||||
this.write_null(&this.deref_operand(result_op)?)?;
|
this.write_null(&this.deref_pointer(result_op)?)?;
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
Some(Err(e)) =>
|
Some(Err(e)) =>
|
||||||
|
|
|
@ -71,7 +71,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||||
let epoll_ctl_del = this.eval_libc_i32("EPOLL_CTL_DEL");
|
let epoll_ctl_del = this.eval_libc_i32("EPOLL_CTL_DEL");
|
||||||
|
|
||||||
if op == epoll_ctl_add || op == epoll_ctl_mod {
|
if op == epoll_ctl_add || op == epoll_ctl_mod {
|
||||||
let event = this.deref_operand_as(event, this.libc_ty_layout("epoll_event"))?;
|
let event = this.deref_pointer_as(event, this.libc_ty_layout("epoll_event"))?;
|
||||||
|
|
||||||
let events = this.project_field(&event, 0)?;
|
let events = this.project_field(&event, 0)?;
|
||||||
let events = this.read_scalar(&events)?.to_u32()?;
|
let events = this.read_scalar(&events)?.to_u32()?;
|
||||||
|
@ -240,7 +240,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||||
let _domain = this.read_scalar(domain)?.to_i32()?;
|
let _domain = this.read_scalar(domain)?.to_i32()?;
|
||||||
let _type_ = this.read_scalar(type_)?.to_i32()?;
|
let _type_ = this.read_scalar(type_)?.to_i32()?;
|
||||||
let _protocol = this.read_scalar(protocol)?.to_i32()?;
|
let _protocol = this.read_scalar(protocol)?.to_i32()?;
|
||||||
let sv = this.deref_operand(sv)?;
|
let sv = this.deref_pointer(sv)?;
|
||||||
|
|
||||||
let fh = &mut this.machine.file_handler;
|
let fh = &mut this.machine.file_handler;
|
||||||
let sv0 = fh.insert_fd(Box::new(SocketPair));
|
let sv0 = fh.insert_fd(Box::new(SocketPair));
|
||||||
|
|
|
@ -198,7 +198,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||||
this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
||||||
this.read_scalar(pid)?.to_i32()?;
|
this.read_scalar(pid)?.to_i32()?;
|
||||||
this.read_target_usize(cpusetsize)?;
|
this.read_target_usize(cpusetsize)?;
|
||||||
this.deref_operand_as(mask, this.libc_ty_layout("cpu_set_t"))?;
|
this.deref_pointer_as(mask, this.libc_ty_layout("cpu_set_t"))?;
|
||||||
// FIXME: we just return an error; `num_cpus` then falls back to `sysconf`.
|
// FIXME: we just return an error; `num_cpus` then falls back to `sysconf`.
|
||||||
let einval = this.eval_libc("EINVAL");
|
let einval = this.eval_libc("EINVAL");
|
||||||
this.set_last_error(einval)?;
|
this.set_last_error(einval)?;
|
||||||
|
|
|
@ -130,7 +130,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||||
this.check_no_isolation("`_NSGetExecutablePath`")?;
|
this.check_no_isolation("`_NSGetExecutablePath`")?;
|
||||||
|
|
||||||
let buf_ptr = this.read_pointer(buf)?;
|
let buf_ptr = this.read_pointer(buf)?;
|
||||||
let bufsize = this.deref_operand(bufsize)?;
|
let bufsize = this.deref_pointer(bufsize)?;
|
||||||
|
|
||||||
// Using the host current_exe is a bit off, but consistent with Linux
|
// Using the host current_exe is a bit off, but consistent with Linux
|
||||||
// (where stdlib reads /proc/self/exe).
|
// (where stdlib reads /proc/self/exe).
|
||||||
|
|
|
@ -36,7 +36,7 @@ fn mutexattr_get_kind<'mir, 'tcx: 'mir>(
|
||||||
ecx: &MiriInterpCx<'mir, 'tcx>,
|
ecx: &MiriInterpCx<'mir, 'tcx>,
|
||||||
attr_op: &OpTy<'tcx, Provenance>,
|
attr_op: &OpTy<'tcx, Provenance>,
|
||||||
) -> InterpResult<'tcx, i32> {
|
) -> InterpResult<'tcx, i32> {
|
||||||
ecx.read_scalar_at_offset(
|
ecx.deref_pointer_and_read(
|
||||||
attr_op,
|
attr_op,
|
||||||
0,
|
0,
|
||||||
ecx.libc_ty_layout("pthread_mutexattr_t"),
|
ecx.libc_ty_layout("pthread_mutexattr_t"),
|
||||||
|
@ -50,7 +50,7 @@ fn mutexattr_set_kind<'mir, 'tcx: 'mir>(
|
||||||
attr_op: &OpTy<'tcx, Provenance>,
|
attr_op: &OpTy<'tcx, Provenance>,
|
||||||
kind: i32,
|
kind: i32,
|
||||||
) -> InterpResult<'tcx, ()> {
|
) -> InterpResult<'tcx, ()> {
|
||||||
ecx.write_scalar_at_offset(
|
ecx.deref_pointer_and_write(
|
||||||
attr_op,
|
attr_op,
|
||||||
0,
|
0,
|
||||||
Scalar::from_i32(kind),
|
Scalar::from_i32(kind),
|
||||||
|
@ -79,7 +79,7 @@ fn mutex_reset_id<'mir, 'tcx: 'mir>(
|
||||||
ecx: &mut MiriInterpCx<'mir, 'tcx>,
|
ecx: &mut MiriInterpCx<'mir, 'tcx>,
|
||||||
mutex_op: &OpTy<'tcx, Provenance>,
|
mutex_op: &OpTy<'tcx, Provenance>,
|
||||||
) -> InterpResult<'tcx, ()> {
|
) -> InterpResult<'tcx, ()> {
|
||||||
ecx.write_scalar_at_offset(
|
ecx.deref_pointer_and_write(
|
||||||
mutex_op,
|
mutex_op,
|
||||||
4,
|
4,
|
||||||
Scalar::from_i32(0),
|
Scalar::from_i32(0),
|
||||||
|
@ -93,7 +93,7 @@ fn mutex_get_kind<'mir, 'tcx: 'mir>(
|
||||||
mutex_op: &OpTy<'tcx, Provenance>,
|
mutex_op: &OpTy<'tcx, Provenance>,
|
||||||
) -> InterpResult<'tcx, i32> {
|
) -> InterpResult<'tcx, i32> {
|
||||||
let offset = if ecx.pointer_size().bytes() == 8 { 16 } else { 12 };
|
let offset = if ecx.pointer_size().bytes() == 8 { 16 } else { 12 };
|
||||||
ecx.read_scalar_at_offset(
|
ecx.deref_pointer_and_read(
|
||||||
mutex_op,
|
mutex_op,
|
||||||
offset,
|
offset,
|
||||||
ecx.libc_ty_layout("pthread_mutex_t"),
|
ecx.libc_ty_layout("pthread_mutex_t"),
|
||||||
|
@ -108,7 +108,7 @@ fn mutex_set_kind<'mir, 'tcx: 'mir>(
|
||||||
kind: i32,
|
kind: i32,
|
||||||
) -> InterpResult<'tcx, ()> {
|
) -> InterpResult<'tcx, ()> {
|
||||||
let offset = if ecx.pointer_size().bytes() == 8 { 16 } else { 12 };
|
let offset = if ecx.pointer_size().bytes() == 8 { 16 } else { 12 };
|
||||||
ecx.write_scalar_at_offset(
|
ecx.deref_pointer_and_write(
|
||||||
mutex_op,
|
mutex_op,
|
||||||
offset,
|
offset,
|
||||||
Scalar::from_i32(kind),
|
Scalar::from_i32(kind),
|
||||||
|
@ -141,7 +141,7 @@ fn condattr_get_clock_id<'mir, 'tcx: 'mir>(
|
||||||
ecx: &MiriInterpCx<'mir, 'tcx>,
|
ecx: &MiriInterpCx<'mir, 'tcx>,
|
||||||
attr_op: &OpTy<'tcx, Provenance>,
|
attr_op: &OpTy<'tcx, Provenance>,
|
||||||
) -> InterpResult<'tcx, i32> {
|
) -> InterpResult<'tcx, i32> {
|
||||||
ecx.read_scalar_at_offset(
|
ecx.deref_pointer_and_read(
|
||||||
attr_op,
|
attr_op,
|
||||||
0,
|
0,
|
||||||
ecx.libc_ty_layout("pthread_condattr_t"),
|
ecx.libc_ty_layout("pthread_condattr_t"),
|
||||||
|
@ -155,7 +155,7 @@ fn condattr_set_clock_id<'mir, 'tcx: 'mir>(
|
||||||
attr_op: &OpTy<'tcx, Provenance>,
|
attr_op: &OpTy<'tcx, Provenance>,
|
||||||
clock_id: i32,
|
clock_id: i32,
|
||||||
) -> InterpResult<'tcx, ()> {
|
) -> InterpResult<'tcx, ()> {
|
||||||
ecx.write_scalar_at_offset(
|
ecx.deref_pointer_and_write(
|
||||||
attr_op,
|
attr_op,
|
||||||
0,
|
0,
|
||||||
Scalar::from_i32(clock_id),
|
Scalar::from_i32(clock_id),
|
||||||
|
@ -184,7 +184,7 @@ fn cond_reset_id<'mir, 'tcx: 'mir>(
|
||||||
ecx: &mut MiriInterpCx<'mir, 'tcx>,
|
ecx: &mut MiriInterpCx<'mir, 'tcx>,
|
||||||
cond_op: &OpTy<'tcx, Provenance>,
|
cond_op: &OpTy<'tcx, Provenance>,
|
||||||
) -> InterpResult<'tcx, ()> {
|
) -> InterpResult<'tcx, ()> {
|
||||||
ecx.write_scalar_at_offset(
|
ecx.deref_pointer_and_write(
|
||||||
cond_op,
|
cond_op,
|
||||||
4,
|
4,
|
||||||
Scalar::from_i32(0),
|
Scalar::from_i32(0),
|
||||||
|
@ -197,7 +197,7 @@ fn cond_get_clock_id<'mir, 'tcx: 'mir>(
|
||||||
ecx: &MiriInterpCx<'mir, 'tcx>,
|
ecx: &MiriInterpCx<'mir, 'tcx>,
|
||||||
cond_op: &OpTy<'tcx, Provenance>,
|
cond_op: &OpTy<'tcx, Provenance>,
|
||||||
) -> InterpResult<'tcx, i32> {
|
) -> InterpResult<'tcx, i32> {
|
||||||
ecx.read_scalar_at_offset(
|
ecx.deref_pointer_and_read(
|
||||||
cond_op,
|
cond_op,
|
||||||
8,
|
8,
|
||||||
ecx.libc_ty_layout("pthread_cond_t"),
|
ecx.libc_ty_layout("pthread_cond_t"),
|
||||||
|
@ -211,7 +211,7 @@ fn cond_set_clock_id<'mir, 'tcx: 'mir>(
|
||||||
cond_op: &OpTy<'tcx, Provenance>,
|
cond_op: &OpTy<'tcx, Provenance>,
|
||||||
clock_id: i32,
|
clock_id: i32,
|
||||||
) -> InterpResult<'tcx, ()> {
|
) -> InterpResult<'tcx, ()> {
|
||||||
ecx.write_scalar_at_offset(
|
ecx.deref_pointer_and_write(
|
||||||
cond_op,
|
cond_op,
|
||||||
8,
|
8,
|
||||||
Scalar::from_i32(clock_id),
|
Scalar::from_i32(clock_id),
|
||||||
|
@ -346,7 +346,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||||
// This can always be revisited to have some external state to catch double-destroys
|
// This can always be revisited to have some external state to catch double-destroys
|
||||||
// but not complain about the above code. See https://github.com/rust-lang/miri/pull/1933
|
// but not complain about the above code. See https://github.com/rust-lang/miri/pull/1933
|
||||||
this.write_uninit(
|
this.write_uninit(
|
||||||
&this.deref_operand_as(attr_op, this.libc_ty_layout("pthread_mutexattr_t"))?,
|
&this.deref_pointer_as(attr_op, this.libc_ty_layout("pthread_mutexattr_t"))?,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
Ok(0)
|
Ok(0)
|
||||||
|
@ -500,7 +500,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||||
|
|
||||||
// This might lead to false positives, see comment in pthread_mutexattr_destroy
|
// This might lead to false positives, see comment in pthread_mutexattr_destroy
|
||||||
this.write_uninit(
|
this.write_uninit(
|
||||||
&this.deref_operand_as(mutex_op, this.libc_ty_layout("pthread_mutex_t"))?,
|
&this.deref_pointer_as(mutex_op, this.libc_ty_layout("pthread_mutex_t"))?,
|
||||||
)?;
|
)?;
|
||||||
// FIXME: delete interpreter state associated with this mutex.
|
// FIXME: delete interpreter state associated with this mutex.
|
||||||
|
|
||||||
|
@ -625,7 +625,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||||
|
|
||||||
// This might lead to false positives, see comment in pthread_mutexattr_destroy
|
// This might lead to false positives, see comment in pthread_mutexattr_destroy
|
||||||
this.write_uninit(
|
this.write_uninit(
|
||||||
&this.deref_operand_as(rwlock_op, this.libc_ty_layout("pthread_rwlock_t"))?,
|
&this.deref_pointer_as(rwlock_op, this.libc_ty_layout("pthread_rwlock_t"))?,
|
||||||
)?;
|
)?;
|
||||||
// FIXME: delete interpreter state associated with this rwlock.
|
// FIXME: delete interpreter state associated with this rwlock.
|
||||||
|
|
||||||
|
@ -675,7 +675,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||||
let this = self.eval_context_mut();
|
let this = self.eval_context_mut();
|
||||||
|
|
||||||
let clock_id = condattr_get_clock_id(this, attr_op)?;
|
let clock_id = condattr_get_clock_id(this, attr_op)?;
|
||||||
this.write_scalar(Scalar::from_i32(clock_id), &this.deref_operand(clk_id_op)?)?;
|
this.write_scalar(Scalar::from_i32(clock_id), &this.deref_pointer(clk_id_op)?)?;
|
||||||
|
|
||||||
Ok(Scalar::from_i32(0))
|
Ok(Scalar::from_i32(0))
|
||||||
}
|
}
|
||||||
|
@ -691,7 +691,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||||
|
|
||||||
// This might lead to false positives, see comment in pthread_mutexattr_destroy
|
// This might lead to false positives, see comment in pthread_mutexattr_destroy
|
||||||
this.write_uninit(
|
this.write_uninit(
|
||||||
&this.deref_operand_as(attr_op, this.libc_ty_layout("pthread_condattr_t"))?,
|
&this.deref_pointer_as(attr_op, this.libc_ty_layout("pthread_condattr_t"))?,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
Ok(0)
|
Ok(0)
|
||||||
|
@ -784,7 +784,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||||
// Extract the timeout.
|
// Extract the timeout.
|
||||||
let clock_id = cond_get_clock_id(this, cond_op)?;
|
let clock_id = cond_get_clock_id(this, cond_op)?;
|
||||||
let duration = match this
|
let duration = match this
|
||||||
.read_timespec(&this.deref_operand_as(abstime_op, this.libc_ty_layout("timespec"))?)?
|
.read_timespec(&this.deref_pointer_as(abstime_op, this.libc_ty_layout("timespec"))?)?
|
||||||
{
|
{
|
||||||
Some(duration) => duration,
|
Some(duration) => duration,
|
||||||
None => {
|
None => {
|
||||||
|
@ -867,7 +867,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||||
cond_get_clock_id(this, cond_op)?;
|
cond_get_clock_id(this, cond_op)?;
|
||||||
|
|
||||||
// This might lead to false positives, see comment in pthread_mutexattr_destroy
|
// This might lead to false positives, see comment in pthread_mutexattr_destroy
|
||||||
this.write_uninit(&this.deref_operand_as(cond_op, this.libc_ty_layout("pthread_cond_t"))?)?;
|
this.write_uninit(&this.deref_pointer_as(cond_op, this.libc_ty_layout("pthread_cond_t"))?)?;
|
||||||
// FIXME: delete interpreter state associated with this condvar.
|
// FIXME: delete interpreter state associated with this condvar.
|
||||||
|
|
||||||
Ok(0)
|
Ok(0)
|
||||||
|
|
|
@ -13,7 +13,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||||
) -> InterpResult<'tcx, i32> {
|
) -> InterpResult<'tcx, i32> {
|
||||||
let this = self.eval_context_mut();
|
let this = self.eval_context_mut();
|
||||||
|
|
||||||
let thread_info_place = this.deref_operand_as(thread, this.libc_ty_layout("pthread_t"))?;
|
let thread_info_place = this.deref_pointer_as(thread, this.libc_ty_layout("pthread_t"))?;
|
||||||
|
|
||||||
let start_routine = this.read_pointer(start_routine)?;
|
let start_routine = this.read_pointer(start_routine)?;
|
||||||
|
|
||||||
|
|
|
@ -91,7 +91,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||||
let n = this.read_scalar(n)?.to_u32()?;
|
let n = this.read_scalar(n)?.to_u32()?;
|
||||||
let byte_offset = this.read_target_usize(byte_offset)?; // is actually a pointer
|
let byte_offset = this.read_target_usize(byte_offset)?; // is actually a pointer
|
||||||
let io_status_block = this
|
let io_status_block = this
|
||||||
.deref_operand_as(io_status_block, this.windows_ty_layout("IO_STATUS_BLOCK"))?;
|
.deref_pointer_as(io_status_block, this.windows_ty_layout("IO_STATUS_BLOCK"))?;
|
||||||
|
|
||||||
if byte_offset != 0 {
|
if byte_offset != 0 {
|
||||||
throw_unsup_format!(
|
throw_unsup_format!(
|
||||||
|
@ -187,7 +187,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||||
let [system_info] =
|
let [system_info] =
|
||||||
this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
|
this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
|
||||||
let system_info =
|
let system_info =
|
||||||
this.deref_operand_as(system_info, this.windows_ty_layout("SYSTEM_INFO"))?;
|
this.deref_pointer_as(system_info, this.windows_ty_layout("SYSTEM_INFO"))?;
|
||||||
// Initialize with `0`.
|
// Initialize with `0`.
|
||||||
this.write_bytes_ptr(
|
this.write_bytes_ptr(
|
||||||
system_info.ptr,
|
system_info.ptr,
|
||||||
|
@ -391,8 +391,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||||
let [console, buffer_info] =
|
let [console, buffer_info] =
|
||||||
this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
|
this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
|
||||||
this.read_target_isize(console)?;
|
this.read_target_isize(console)?;
|
||||||
// FIXME: this should use deref_operand_as, but CONSOLE_SCREEN_BUFFER_INFO is not in std
|
// FIXME: this should use deref_pointer_as, but CONSOLE_SCREEN_BUFFER_INFO is not in std
|
||||||
this.deref_operand(buffer_info)?;
|
this.deref_pointer(buffer_info)?;
|
||||||
// Indicate an error.
|
// Indicate an error.
|
||||||
// FIXME: we should set last_error, but to what?
|
// FIXME: we should set last_error, but to what?
|
||||||
this.write_null(dest)?;
|
this.write_null(dest)?;
|
||||||
|
@ -508,7 +508,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||||
let [console, mode] =
|
let [console, mode] =
|
||||||
this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
|
this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
|
||||||
this.read_target_isize(console)?;
|
this.read_target_isize(console)?;
|
||||||
this.deref_operand(mode)?;
|
this.deref_pointer(mode)?;
|
||||||
// Indicate an error.
|
// Indicate an error.
|
||||||
this.write_null(dest)?;
|
this.write_null(dest)?;
|
||||||
}
|
}
|
||||||
|
|
|
@ -179,7 +179,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||||
|
|
||||||
let id = this.init_once_get_id(init_once_op)?;
|
let id = this.init_once_get_id(init_once_op)?;
|
||||||
let flags = this.read_scalar(flags_op)?.to_u32()?;
|
let flags = this.read_scalar(flags_op)?.to_u32()?;
|
||||||
let pending_place = this.deref_operand(pending_op)?.into();
|
let pending_place = this.deref_pointer(pending_op)?.into();
|
||||||
let context = this.read_pointer(context_op)?;
|
let context = this.read_pointer(context_op)?;
|
||||||
|
|
||||||
if flags != 0 {
|
if flags != 0 {
|
||||||
|
|
|
@ -29,7 +29,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||||
let thread = if this.ptr_is_null(this.read_pointer(thread_op)?)? {
|
let thread = if this.ptr_is_null(this.read_pointer(thread_op)?)? {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
let thread_info_place = this.deref_operand(thread_op)?;
|
let thread_info_place = this.deref_pointer(thread_op)?;
|
||||||
Some(thread_info_place)
|
Some(thread_info_place)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue