Merge from rustc
This commit is contained in:
commit
044aa87d78
273 changed files with 2128 additions and 7332 deletions
|
|
@ -54,7 +54,7 @@ impl<'tcx> LateLintPass<'tcx> for LargeConstArrays {
|
|||
let ty = hir_ty_to_ty(cx.tcx, hir_ty);
|
||||
if let ty::Array(element_type, cst) = ty.kind();
|
||||
if let ConstKind::Value(ty::ValTree::Leaf(element_count)) = cst.kind();
|
||||
if let Ok(element_count) = element_count.try_to_machine_usize(cx.tcx);
|
||||
if let Ok(element_count) = element_count.try_to_target_usize(cx.tcx);
|
||||
if let Ok(element_size) = cx.layout_of(*element_type).map(|l| l.size.bytes());
|
||||
if self.maximum_allowed_size < u128::from(element_count) * u128::from(element_size);
|
||||
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ impl<'tcx> LateLintPass<'tcx> for LargeStackArrays {
|
|||
if let ExprKind::Repeat(_, _) = expr.kind
|
||||
&& let ty::Array(element_type, cst) = cx.typeck_results().expr_ty(expr).kind()
|
||||
&& let ConstKind::Value(ty::ValTree::Leaf(element_count)) = cst.kind()
|
||||
&& let Ok(element_count) = element_count.try_to_machine_usize(cx.tcx)
|
||||
&& let Ok(element_count) = element_count.try_to_target_usize(cx.tcx)
|
||||
&& let Ok(element_size) = cx.layout_of(*element_type).map(|l| l.size.bytes())
|
||||
&& !cx.tcx.hir().parent_iter(expr.hir_id)
|
||||
.any(|(_, node)| matches!(node, Node::Item(Item { kind: ItemKind::Static(..), .. })))
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ impl<'tcx> LateLintPass<'tcx> for SameNameMethod {
|
|||
let mut map = FxHashMap::<Res, ExistingName>::default();
|
||||
|
||||
for id in cx.tcx.hir().items() {
|
||||
if matches!(cx.tcx.def_kind(id.owner_id), DefKind::Impl)
|
||||
if matches!(cx.tcx.def_kind(id.owner_id), DefKind::Impl { .. })
|
||||
&& let item = cx.tcx.hir().item(id)
|
||||
&& let ItemKind::Impl(Impl {
|
||||
items,
|
||||
|
|
|
|||
|
|
@ -640,7 +640,7 @@ pub fn miri_to_const<'tcx>(tcx: TyCtxt<'tcx>, result: mir::ConstantKind<'tcx>) -
|
|||
},
|
||||
mir::ConstantKind::Val(ConstValue::ByRef { alloc, offset: _ }, _) => match result.ty().kind() {
|
||||
ty::Array(sub_type, len) => match sub_type.kind() {
|
||||
ty::Float(FloatTy::F32) => match len.kind().try_to_machine_usize(tcx) {
|
||||
ty::Float(FloatTy::F32) => match len.kind().try_to_target_usize(tcx) {
|
||||
Some(len) => alloc
|
||||
.inner()
|
||||
.inspect_with_uninit_and_ptr_outside_interpreter(0..(4 * usize::try_from(len).unwrap()))
|
||||
|
|
@ -651,7 +651,7 @@ pub fn miri_to_const<'tcx>(tcx: TyCtxt<'tcx>, result: mir::ConstantKind<'tcx>) -
|
|||
.map(Constant::Vec),
|
||||
_ => None,
|
||||
},
|
||||
ty::Float(FloatTy::F64) => match len.kind().try_to_machine_usize(tcx) {
|
||||
ty::Float(FloatTy::F64) => match len.kind().try_to_target_usize(tcx) {
|
||||
Some(len) => alloc
|
||||
.inner()
|
||||
.inspect_with_uninit_and_ptr_outside_interpreter(0..(8 * usize::try_from(len).unwrap()))
|
||||
|
|
|
|||
|
|
@ -552,7 +552,7 @@ fn non_local_item_children_by_name(tcx: TyCtxt<'_>, def_id: DefId, name: Symbol)
|
|||
.filter(|item| item.ident.name == name)
|
||||
.map(|child| child.res.expect_non_local())
|
||||
.collect(),
|
||||
DefKind::Impl => tcx
|
||||
DefKind::Impl { .. } => tcx
|
||||
.associated_item_def_ids(def_id)
|
||||
.iter()
|
||||
.copied()
|
||||
|
|
|
|||
|
|
@ -717,7 +717,7 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<'
|
|||
throw_ub!(PointerOutOfBounds {
|
||||
alloc_id,
|
||||
alloc_size,
|
||||
ptr_offset: this.machine_usize_to_isize(base_offset.bytes()),
|
||||
ptr_offset: this.target_usize_to_isize(base_offset.bytes()),
|
||||
ptr_size: size,
|
||||
msg: CheckInAllocMsg::InboundsTest
|
||||
});
|
||||
|
|
|
|||
|
|
@ -236,7 +236,7 @@ impl MainThreadState {
|
|||
this.machine.main_fn_ret_place.unwrap().ptr,
|
||||
this.machine.layouts.isize,
|
||||
);
|
||||
let exit_code = this.read_machine_isize(&ret_place.into())?;
|
||||
let exit_code = this.read_target_isize(&ret_place.into())?;
|
||||
// Need to call this ourselves since we are not going to return to the scheduler
|
||||
// loop, and we want the main thread TLS to not show up as memory leaks.
|
||||
this.terminate_active_thread()?;
|
||||
|
|
@ -287,7 +287,7 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
|
|||
// First argument is constructed later, because it's skipped if the entry function uses #[start].
|
||||
|
||||
// Second argument (argc): length of `config.args`.
|
||||
let argc = Scalar::from_machine_usize(u64::try_from(config.args.len()).unwrap(), &ecx);
|
||||
let argc = Scalar::from_target_usize(u64::try_from(config.args.len()).unwrap(), &ecx);
|
||||
// Third argument (`argv`): created from `config.args`.
|
||||
let argv = {
|
||||
// Put each argument in memory, collect pointers.
|
||||
|
|
|
|||
|
|
@ -758,10 +758,10 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
let this = self.eval_context_mut();
|
||||
let seconds_place = this.mplace_field(tp, 0)?;
|
||||
let seconds_scalar = this.read_scalar(&seconds_place.into())?;
|
||||
let seconds = seconds_scalar.to_machine_isize(this)?;
|
||||
let seconds = seconds_scalar.to_target_isize(this)?;
|
||||
let nanoseconds_place = this.mplace_field(tp, 1)?;
|
||||
let nanoseconds_scalar = this.read_scalar(&nanoseconds_place.into())?;
|
||||
let nanoseconds = nanoseconds_scalar.to_machine_isize(this)?;
|
||||
let nanoseconds = nanoseconds_scalar.to_target_isize(this)?;
|
||||
|
||||
Ok(try {
|
||||
// tv_sec must be non-negative.
|
||||
|
|
|
|||
|
|
@ -207,7 +207,7 @@ impl<'mir, 'tcx> GlobalStateInner {
|
|||
.checked_add(max(size.bytes(), 1))
|
||||
.ok_or_else(|| err_exhaust!(AddressSpaceFull))?;
|
||||
// Even if `Size` didn't overflow, we might still have filled up the address space.
|
||||
if global_state.next_base_addr > ecx.machine_usize_max() {
|
||||
if global_state.next_base_addr > ecx.target_usize_max() {
|
||||
throw_exhaust!(AddressSpaceFull);
|
||||
}
|
||||
// Given that `next_base_addr` increases in each allocation, pushing the
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ impl<'mir, 'tcx> EvalContextExt<'tcx> for super::MiriInterpCx<'mir, 'tcx> {
|
|||
Offset => {
|
||||
assert!(left.layout.ty.is_unsafe_ptr());
|
||||
let ptr = left.to_scalar().to_pointer(self)?;
|
||||
let offset = right.to_scalar().to_machine_isize(self)?;
|
||||
let offset = right.to_scalar().to_target_isize(self)?;
|
||||
|
||||
let pointee_ty =
|
||||
left.layout.ty.builtin_deref(true).expect("Offset called on non-ptr type").ty;
|
||||
|
|
@ -73,14 +73,14 @@ impl<'mir, 'tcx> EvalContextExt<'tcx> for super::MiriInterpCx<'mir, 'tcx> {
|
|||
// We do the actual operation with usize-typed scalars.
|
||||
let left = ImmTy::from_uint(ptr.addr().bytes(), self.machine.layouts.usize);
|
||||
let right = ImmTy::from_uint(
|
||||
right.to_scalar().to_machine_usize(self)?,
|
||||
right.to_scalar().to_target_usize(self)?,
|
||||
self.machine.layouts.usize,
|
||||
);
|
||||
let (result, overflowing, _ty) =
|
||||
self.overflowing_binary_op(bin_op, &left, &right)?;
|
||||
// Construct a new pointer with the provenance of `ptr` (the LHS).
|
||||
let result_ptr =
|
||||
Pointer::new(ptr.provenance, Size::from_bytes(result.to_machine_usize(self)?));
|
||||
Pointer::new(ptr.provenance, Size::from_bytes(result.to_target_usize(self)?));
|
||||
(Scalar::from_maybe_pointer(result_ptr, self), overflowing, left.layout.ty)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
|
||||
let frame_count = this.active_thread_stack().len();
|
||||
|
||||
this.write_scalar(Scalar::from_machine_usize(frame_count.try_into().unwrap(), this), dest)
|
||||
this.write_scalar(Scalar::from_target_usize(frame_count.try_into().unwrap(), this), dest)
|
||||
}
|
||||
|
||||
fn handle_miri_get_backtrace(
|
||||
|
|
@ -205,11 +205,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
}
|
||||
1 => {
|
||||
this.write_scalar(
|
||||
Scalar::from_machine_usize(name.len().try_into().unwrap(), this),
|
||||
Scalar::from_target_usize(name.len().try_into().unwrap(), this),
|
||||
&this.mplace_field(&dest, 0)?.into(),
|
||||
)?;
|
||||
this.write_scalar(
|
||||
Scalar::from_machine_usize(filename.len().try_into().unwrap(), this),
|
||||
Scalar::from_target_usize(filename.len().try_into().unwrap(), this),
|
||||
&this.mplace_field(&dest, 1)?.into(),
|
||||
)?;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -323,7 +323,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
this.assert_target_os_is_unix("getcwd");
|
||||
|
||||
let buf = this.read_pointer(buf_op)?;
|
||||
let size = this.read_machine_usize(size_op)?;
|
||||
let size = this.read_target_usize(size_op)?;
|
||||
|
||||
if let IsolatedOp::Reject(reject_with) = this.machine.isolated_op {
|
||||
this.reject_in_isolation("`getcwd`", reject_with)?;
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
ty::Int(IntTy::Isize) => {
|
||||
// This will fail if host != target, but then the entire FFI thing probably won't work well
|
||||
// in that situation.
|
||||
return Ok(CArg::ISize(k.to_machine_isize(cx)?.try_into().unwrap()));
|
||||
return Ok(CArg::ISize(k.to_target_isize(cx)?.try_into().unwrap()));
|
||||
}
|
||||
// the uints
|
||||
ty::Uint(UintTy::U8) => {
|
||||
|
|
@ -54,7 +54,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
ty::Uint(UintTy::Usize) => {
|
||||
// This will fail if host != target, but then the entire FFI thing probably won't work well
|
||||
// in that situation.
|
||||
return Ok(CArg::USize(k.to_machine_usize(cx)?.try_into().unwrap()));
|
||||
return Ok(CArg::USize(k.to_target_usize(cx)?.try_into().unwrap()));
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -449,7 +449,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
let [ptr, out, out_size] = this.check_shim(abi, Abi::Rust, link_name, args)?;
|
||||
let ptr = this.read_pointer(ptr)?;
|
||||
let out = this.read_pointer(out)?;
|
||||
let out_size = this.read_scalar(out_size)?.to_machine_usize(this)?;
|
||||
let out_size = this.read_scalar(out_size)?.to_target_usize(this)?;
|
||||
|
||||
// The host affects program behavior here, so this requires isolation to be disabled.
|
||||
this.check_no_isolation("`miri_host_to_target_path`")?;
|
||||
|
|
@ -490,7 +490,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
let [bytes] = this.check_shim(abi, Abi::Rust, link_name, args)?;
|
||||
let (ptr, len) = this.read_immediate(bytes)?.to_scalar_pair();
|
||||
let ptr = ptr.to_pointer(this)?;
|
||||
let len = len.to_machine_usize(this)?;
|
||||
let len = len.to_target_usize(this)?;
|
||||
let msg = this.read_bytes_ptr_strip_provenance(ptr, Size::from_bytes(len))?;
|
||||
|
||||
// Note: we're ignoring errors writing to host stdout/stderr.
|
||||
|
|
@ -504,15 +504,15 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
// Standard C allocation
|
||||
"malloc" => {
|
||||
let [size] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
||||
let size = this.read_machine_usize(size)?;
|
||||
let size = this.read_target_usize(size)?;
|
||||
let res = this.malloc(size, /*zero_init:*/ false, MiriMemoryKind::C)?;
|
||||
this.write_pointer(res, dest)?;
|
||||
}
|
||||
"calloc" => {
|
||||
let [items, len] =
|
||||
this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
||||
let items = this.read_machine_usize(items)?;
|
||||
let len = this.read_machine_usize(len)?;
|
||||
let items = this.read_target_usize(items)?;
|
||||
let len = this.read_target_usize(len)?;
|
||||
let size = items
|
||||
.checked_mul(len)
|
||||
.ok_or_else(|| err_ub_format!("overflow during calloc size computation"))?;
|
||||
|
|
@ -528,7 +528,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
let [old_ptr, new_size] =
|
||||
this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
||||
let old_ptr = this.read_pointer(old_ptr)?;
|
||||
let new_size = this.read_machine_usize(new_size)?;
|
||||
let new_size = this.read_target_usize(new_size)?;
|
||||
let res = this.realloc(old_ptr, new_size, MiriMemoryKind::C)?;
|
||||
this.write_pointer(res, dest)?;
|
||||
}
|
||||
|
|
@ -536,8 +536,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
// Rust allocation
|
||||
"__rust_alloc" | "miri_alloc" => {
|
||||
let [size, align] = this.check_shim(abi, Abi::Rust, link_name, args)?;
|
||||
let size = this.read_machine_usize(size)?;
|
||||
let align = this.read_machine_usize(align)?;
|
||||
let size = this.read_target_usize(size)?;
|
||||
let align = this.read_target_usize(align)?;
|
||||
|
||||
let default = |this: &mut MiriInterpCx<'mir, 'tcx>| {
|
||||
Self::check_alloc_request(size, align)?;
|
||||
|
|
@ -569,8 +569,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
}
|
||||
"__rust_alloc_zeroed" => {
|
||||
let [size, align] = this.check_shim(abi, Abi::Rust, link_name, args)?;
|
||||
let size = this.read_machine_usize(size)?;
|
||||
let align = this.read_machine_usize(align)?;
|
||||
let size = this.read_target_usize(size)?;
|
||||
let align = this.read_target_usize(align)?;
|
||||
|
||||
return this.emulate_allocator(Symbol::intern("__rg_alloc_zeroed"), |this| {
|
||||
Self::check_alloc_request(size, align)?;
|
||||
|
|
@ -593,8 +593,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
"__rust_dealloc" | "miri_dealloc" => {
|
||||
let [ptr, old_size, align] = this.check_shim(abi, Abi::Rust, link_name, args)?;
|
||||
let ptr = this.read_pointer(ptr)?;
|
||||
let old_size = this.read_machine_usize(old_size)?;
|
||||
let align = this.read_machine_usize(align)?;
|
||||
let old_size = this.read_target_usize(old_size)?;
|
||||
let align = this.read_target_usize(align)?;
|
||||
|
||||
let default = |this: &mut MiriInterpCx<'mir, 'tcx>| {
|
||||
let memory_kind = match link_name.as_str() {
|
||||
|
|
@ -625,9 +625,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
let [ptr, old_size, align, new_size] =
|
||||
this.check_shim(abi, Abi::Rust, link_name, args)?;
|
||||
let ptr = this.read_pointer(ptr)?;
|
||||
let old_size = this.read_machine_usize(old_size)?;
|
||||
let align = this.read_machine_usize(align)?;
|
||||
let new_size = this.read_machine_usize(new_size)?;
|
||||
let old_size = this.read_target_usize(old_size)?;
|
||||
let align = this.read_target_usize(align)?;
|
||||
let new_size = this.read_target_usize(new_size)?;
|
||||
// No need to check old_size; we anyway check that they match the allocation.
|
||||
|
||||
return this.emulate_allocator(Symbol::intern("__rg_realloc"), |this| {
|
||||
|
|
@ -651,7 +651,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
||||
let left = this.read_pointer(left)?;
|
||||
let right = this.read_pointer(right)?;
|
||||
let n = Size::from_bytes(this.read_machine_usize(n)?);
|
||||
let n = Size::from_bytes(this.read_target_usize(n)?);
|
||||
|
||||
let result = {
|
||||
let left_bytes = this.read_bytes_ptr_strip_provenance(left, n)?;
|
||||
|
|
@ -672,7 +672,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
||||
let ptr = this.read_pointer(ptr)?;
|
||||
let val = this.read_scalar(val)?.to_i32()?;
|
||||
let num = this.read_machine_usize(num)?;
|
||||
let num = this.read_target_usize(num)?;
|
||||
// The docs say val is "interpreted as unsigned char".
|
||||
#[allow(clippy::cast_sign_loss, clippy::cast_possible_truncation)]
|
||||
let val = val as u8;
|
||||
|
|
@ -696,7 +696,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
||||
let ptr = this.read_pointer(ptr)?;
|
||||
let val = this.read_scalar(val)?.to_i32()?;
|
||||
let num = this.read_machine_usize(num)?;
|
||||
let num = this.read_target_usize(num)?;
|
||||
// The docs say val is "interpreted as unsigned char".
|
||||
#[allow(clippy::cast_sign_loss, clippy::cast_possible_truncation)]
|
||||
let val = val as u8;
|
||||
|
|
@ -717,7 +717,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
let ptr = this.read_pointer(ptr)?;
|
||||
let n = this.read_c_str(ptr)?.len();
|
||||
this.write_scalar(
|
||||
Scalar::from_machine_usize(u64::try_from(n).unwrap(), this),
|
||||
Scalar::from_target_usize(u64::try_from(n).unwrap(), this),
|
||||
dest,
|
||||
)?;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -111,8 +111,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
let ty_layout = this.layout_of(ty)?;
|
||||
let val_byte = this.read_scalar(val_byte)?.to_u8()?;
|
||||
let ptr = this.read_pointer(ptr)?;
|
||||
let count = this.read_machine_usize(count)?;
|
||||
// `checked_mul` enforces a too small bound (the correct one would probably be machine_isize_max),
|
||||
let count = this.read_target_usize(count)?;
|
||||
// `checked_mul` enforces a too small bound (the correct one would probably be target_isize_max),
|
||||
// but no actual allocation can be big enough for the difference to be noticeable.
|
||||
let byte_count = ty_layout.size.checked_mul(count, this).ok_or_else(|| {
|
||||
err_ub_format!("overflow computing total size of `{intrinsic_name}`")
|
||||
|
|
@ -124,7 +124,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
let [ptr, mask] = check_arg_count(args)?;
|
||||
|
||||
let ptr = this.read_pointer(ptr)?;
|
||||
let mask = this.read_machine_usize(mask)?;
|
||||
let mask = this.read_target_usize(mask)?;
|
||||
|
||||
let masked_addr = Size::from_bytes(ptr.addr().bytes() & mask);
|
||||
|
||||
|
|
|
|||
|
|
@ -202,7 +202,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
}
|
||||
Op::WrappingOffset => {
|
||||
let ptr = left.to_scalar().to_pointer(this)?;
|
||||
let offset_count = right.to_scalar().to_machine_isize(this)?;
|
||||
let offset_count = right.to_scalar().to_target_isize(this)?;
|
||||
let pointee_ty = left.layout.ty.builtin_deref(true).unwrap().ty;
|
||||
|
||||
let pointee_size = i64::try_from(this.layout_of(pointee_ty)?.size.bytes()).unwrap();
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
return Ok(false);
|
||||
}
|
||||
|
||||
let req_align = this.read_machine_usize(align_op)?;
|
||||
let req_align = this.read_target_usize(align_op)?;
|
||||
|
||||
// Stop if the alignment is not a power of two.
|
||||
if !req_align.is_power_of_two() {
|
||||
|
|
@ -106,7 +106,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
}
|
||||
|
||||
// Return error result (usize::MAX), and jump to caller.
|
||||
this.write_scalar(Scalar::from_machine_usize(this.machine_usize_max(), this), dest)?;
|
||||
this.write_scalar(Scalar::from_target_usize(this.target_usize_max(), this), dest)?;
|
||||
this.go_to_block(ret);
|
||||
Ok(true)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -108,7 +108,7 @@ impl<'tcx> TlsData<'tcx> {
|
|||
) -> InterpResult<'tcx> {
|
||||
match self.keys.get_mut(&key) {
|
||||
Some(TlsEntry { data, .. }) => {
|
||||
if new_data.to_machine_usize(cx)? != 0 {
|
||||
if new_data.to_target_usize(cx)? != 0 {
|
||||
trace!("TLS key {} for thread {:?} stored: {:?}", key, thread_id, new_data);
|
||||
data.insert(thread_id, new_data);
|
||||
} else {
|
||||
|
|
@ -356,7 +356,7 @@ trait EvalContextPrivExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
state.last_key = Some(key);
|
||||
trace!("Running TLS dtor {:?} on {:?} at {:?}", instance, ptr, active_thread);
|
||||
assert!(
|
||||
!ptr.to_machine_usize(this).unwrap() != 0,
|
||||
!ptr.to_target_usize(this).unwrap() != 0,
|
||||
"data can't be NULL when dtor is called!"
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -78,19 +78,19 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
let [fd, buf, count] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
||||
let fd = this.read_scalar(fd)?.to_i32()?;
|
||||
let buf = this.read_pointer(buf)?;
|
||||
let count = this.read_machine_usize(count)?;
|
||||
let count = this.read_target_usize(count)?;
|
||||
let result = this.read(fd, buf, count)?;
|
||||
this.write_scalar(Scalar::from_machine_isize(result, this), dest)?;
|
||||
this.write_scalar(Scalar::from_target_isize(result, this), dest)?;
|
||||
}
|
||||
"write" => {
|
||||
let [fd, buf, n] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
||||
let fd = this.read_scalar(fd)?.to_i32()?;
|
||||
let buf = this.read_pointer(buf)?;
|
||||
let count = this.read_machine_usize(n)?;
|
||||
let count = this.read_target_usize(n)?;
|
||||
trace!("Called write({:?}, {:?}, {:?})", fd, buf, count);
|
||||
let result = this.write(fd, buf, count)?;
|
||||
// Now, `result` is the value we return back to the program.
|
||||
this.write_scalar(Scalar::from_machine_isize(result, this), dest)?;
|
||||
this.write_scalar(Scalar::from_target_isize(result, this), dest)?;
|
||||
}
|
||||
"unlink" => {
|
||||
let [path] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
||||
|
|
@ -151,14 +151,14 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
"readlink" => {
|
||||
let [pathname, buf, bufsize] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
||||
let result = this.readlink(pathname, buf, bufsize)?;
|
||||
this.write_scalar(Scalar::from_machine_isize(result, this), dest)?;
|
||||
this.write_scalar(Scalar::from_target_isize(result, this), dest)?;
|
||||
}
|
||||
"posix_fadvise" => {
|
||||
let [fd, offset, len, advice] =
|
||||
this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
||||
this.read_scalar(fd)?.to_i32()?;
|
||||
this.read_machine_isize(offset)?;
|
||||
this.read_machine_isize(len)?;
|
||||
this.read_target_isize(offset)?;
|
||||
this.read_target_isize(len)?;
|
||||
this.read_scalar(advice)?.to_i32()?;
|
||||
// fadvise is only informational, we can ignore it.
|
||||
this.write_null(dest)?;
|
||||
|
|
@ -191,8 +191,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
"posix_memalign" => {
|
||||
let [ret, align, size] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
||||
let ret = this.deref_operand(ret)?;
|
||||
let align = this.read_machine_usize(align)?;
|
||||
let size = this.read_machine_usize(size)?;
|
||||
let align = this.read_target_usize(align)?;
|
||||
let size = this.read_target_usize(size)?;
|
||||
// Align must be power of 2, and also at least ptr-sized (POSIX rules).
|
||||
// But failure to adhere to this is not UB, it's an error condition.
|
||||
if !align.is_power_of_two() || align < this.pointer_size().bytes() {
|
||||
|
|
@ -216,7 +216,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
// Dynamic symbol loading
|
||||
"dlsym" => {
|
||||
let [handle, symbol] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
||||
this.read_machine_usize(handle)?;
|
||||
this.read_target_usize(handle)?;
|
||||
let symbol = this.read_pointer(symbol)?;
|
||||
let symbol_name = this.read_c_str(symbol)?;
|
||||
if let Some(dlsym) = Dlsym::from_str(symbol_name, &this.tcx.sess.target.os)? {
|
||||
|
|
@ -472,7 +472,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
let [errnum, buf, buflen] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
||||
let errnum = this.read_scalar(errnum)?;
|
||||
let buf = this.read_pointer(buf)?;
|
||||
let buflen = this.read_machine_usize(buflen)?;
|
||||
let buflen = this.read_target_usize(buflen)?;
|
||||
|
||||
let error = this.try_errnum_to_io_error(errnum)?;
|
||||
let formatted = match error {
|
||||
|
|
@ -565,7 +565,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
let uid = this.read_scalar(uid)?.to_u32()?;
|
||||
let pwd = this.deref_operand(pwd)?;
|
||||
let buf = this.read_pointer(buf)?;
|
||||
let buflen = this.read_machine_usize(buflen)?;
|
||||
let buflen = this.read_target_usize(buflen)?;
|
||||
let result = this.deref_operand(result)?;
|
||||
|
||||
// Must be for "us".
|
||||
|
|
|
|||
|
|
@ -754,7 +754,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
// We cap the number of read bytes to the largest value that we are able to fit in both the
|
||||
// host's and target's `isize`. This saves us from having to handle overflows later.
|
||||
let count = count
|
||||
.min(u64::try_from(this.machine_isize_max()).unwrap())
|
||||
.min(u64::try_from(this.target_isize_max()).unwrap())
|
||||
.min(u64::try_from(isize::MAX).unwrap());
|
||||
let communicate = this.machine.communicate();
|
||||
|
||||
|
|
@ -807,7 +807,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
// We cap the number of written bytes to the largest value that we are able to fit in both the
|
||||
// host's and target's `isize`. This saves us from having to handle overflows later.
|
||||
let count = count
|
||||
.min(u64::try_from(this.machine_isize_max()).unwrap())
|
||||
.min(u64::try_from(this.target_isize_max()).unwrap())
|
||||
.min(u64::try_from(isize::MAX).unwrap());
|
||||
let communicate = this.machine.communicate();
|
||||
|
||||
|
|
@ -1290,7 +1290,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
// The libc API for opendir says that this method returns a pointer to an opaque
|
||||
// structure, but we are returning an ID number. Thus, pass it as a scalar of
|
||||
// pointer width.
|
||||
Ok(Scalar::from_machine_usize(id, this))
|
||||
Ok(Scalar::from_target_usize(id, this))
|
||||
}
|
||||
Err(e) => {
|
||||
this.set_last_error_from_io_error(e.kind())?;
|
||||
|
|
@ -1307,7 +1307,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
|
||||
this.assert_target_os("linux", "readdir64");
|
||||
|
||||
let dirp = this.read_machine_usize(dirp_op)?;
|
||||
let dirp = this.read_target_usize(dirp_op)?;
|
||||
|
||||
// Reject if isolation is enabled.
|
||||
if let IsolatedOp::Reject(reject_with) = this.machine.isolated_op {
|
||||
|
|
@ -1399,7 +1399,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
|
||||
this.assert_target_os("macos", "readdir_r");
|
||||
|
||||
let dirp = this.read_machine_usize(dirp_op)?;
|
||||
let dirp = this.read_target_usize(dirp_op)?;
|
||||
|
||||
// Reject if isolation is enabled.
|
||||
if let IsolatedOp::Reject(reject_with) = this.machine.isolated_op {
|
||||
|
|
@ -1492,7 +1492,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
fn closedir(&mut self, dirp_op: &OpTy<'tcx, Provenance>) -> InterpResult<'tcx, i32> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
let dirp = this.read_machine_usize(dirp_op)?;
|
||||
let dirp = this.read_target_usize(dirp_op)?;
|
||||
|
||||
// Reject if isolation is enabled.
|
||||
if let IsolatedOp::Reject(reject_with) = this.machine.isolated_op {
|
||||
|
|
@ -1656,7 +1656,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
|
||||
let pathname = this.read_path_from_c_str(this.read_pointer(pathname_op)?)?;
|
||||
let buf = this.read_pointer(buf_op)?;
|
||||
let bufsize = this.read_machine_usize(bufsize_op)?;
|
||||
let bufsize = this.read_target_usize(bufsize_op)?;
|
||||
|
||||
// Reject if isolation is enabled.
|
||||
if let IsolatedOp::Reject(reject_with) = this.machine.isolated_op {
|
||||
|
|
@ -1727,7 +1727,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
this.reject_in_isolation("`realpath`", reject_with)?;
|
||||
let eacc = this.eval_libc("EACCES");
|
||||
this.set_last_error(eacc)?;
|
||||
return Ok(Scalar::from_machine_usize(0, this));
|
||||
return Ok(Scalar::from_target_usize(0, this));
|
||||
}
|
||||
|
||||
let result = std::fs::canonicalize(pathname);
|
||||
|
|
@ -1758,7 +1758,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
// seems like a bit of a mess anyway: <https://eklitzke.org/path-max-is-tricky>.
|
||||
let enametoolong = this.eval_libc("ENAMETOOLONG");
|
||||
this.set_last_error(enametoolong)?;
|
||||
return Ok(Scalar::from_machine_usize(0, this));
|
||||
return Ok(Scalar::from_target_usize(0, this));
|
||||
}
|
||||
processed_ptr
|
||||
};
|
||||
|
|
@ -1767,7 +1767,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
}
|
||||
Err(e) => {
|
||||
this.set_last_error_from_io_error(e.kind())?;
|
||||
Ok(Scalar::from_machine_usize(0, this))
|
||||
Ok(Scalar::from_target_usize(0, this))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -125,18 +125,18 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
// argument, we have to also check all arguments *before* it to ensure that they
|
||||
// have the right type.
|
||||
|
||||
let sys_getrandom = this.eval_libc("SYS_getrandom").to_machine_usize(this)?;
|
||||
let sys_getrandom = this.eval_libc("SYS_getrandom").to_target_usize(this)?;
|
||||
|
||||
let sys_statx = this.eval_libc("SYS_statx").to_machine_usize(this)?;
|
||||
let sys_statx = this.eval_libc("SYS_statx").to_target_usize(this)?;
|
||||
|
||||
let sys_futex = this.eval_libc("SYS_futex").to_machine_usize(this)?;
|
||||
let sys_futex = this.eval_libc("SYS_futex").to_target_usize(this)?;
|
||||
|
||||
if args.is_empty() {
|
||||
throw_ub_format!(
|
||||
"incorrect number of arguments for syscall: got 0, expected at least 1"
|
||||
);
|
||||
}
|
||||
match this.read_machine_usize(&args[0])? {
|
||||
match this.read_target_usize(&args[0])? {
|
||||
// `libc::syscall(NR_GETRANDOM, buf.as_mut_ptr(), buf.len(), GRND_NONBLOCK)`
|
||||
// is called if a `HashMap` is created the regular way (e.g. HashMap<K, V>).
|
||||
id if id == sys_getrandom => {
|
||||
|
|
@ -161,7 +161,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
}
|
||||
let result =
|
||||
this.linux_statx(&args[1], &args[2], &args[3], &args[4], &args[5])?;
|
||||
this.write_scalar(Scalar::from_machine_isize(result.into(), this), dest)?;
|
||||
this.write_scalar(Scalar::from_target_isize(result.into(), this), dest)?;
|
||||
}
|
||||
// `futex` is used by some synchonization primitives.
|
||||
id if id == sys_futex => {
|
||||
|
|
@ -184,7 +184,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
let [pid, cpusetsize, mask] =
|
||||
this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
||||
this.read_scalar(pid)?.to_i32()?;
|
||||
this.read_machine_usize(cpusetsize)?;
|
||||
this.read_target_usize(cpusetsize)?;
|
||||
this.deref_operand(mask)?;
|
||||
// FIXME: we just return an error; `num_cpus` then falls back to `sysconf`.
|
||||
let einval = this.eval_libc("EINVAL");
|
||||
|
|
@ -216,7 +216,7 @@ fn getrandom<'tcx>(
|
|||
dest: &PlaceTy<'tcx, Provenance>,
|
||||
) -> InterpResult<'tcx> {
|
||||
let ptr = this.read_pointer(ptr)?;
|
||||
let len = this.read_machine_usize(len)?;
|
||||
let len = this.read_target_usize(len)?;
|
||||
|
||||
// The only supported flags are GRND_RANDOM and GRND_NONBLOCK,
|
||||
// neither of which have any effect on our current PRNG.
|
||||
|
|
@ -224,6 +224,6 @@ fn getrandom<'tcx>(
|
|||
let _flags = this.read_scalar(flags)?.to_i32();
|
||||
|
||||
this.gen_random(ptr, len)?;
|
||||
this.write_scalar(Scalar::from_machine_usize(len, this), dest)?;
|
||||
this.write_scalar(Scalar::from_target_usize(len, this), dest)?;
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ pub fn futex<'tcx>(
|
|||
if bitset == 0 {
|
||||
let einval = this.eval_libc("EINVAL");
|
||||
this.set_last_error(einval)?;
|
||||
this.write_scalar(Scalar::from_machine_isize(-1, this), dest)?;
|
||||
this.write_scalar(Scalar::from_target_isize(-1, this), dest)?;
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
|
|
@ -101,7 +101,7 @@ pub fn futex<'tcx>(
|
|||
None => {
|
||||
let einval = this.eval_libc("EINVAL");
|
||||
this.set_last_error(einval)?;
|
||||
this.write_scalar(Scalar::from_machine_isize(-1, this), dest)?;
|
||||
this.write_scalar(Scalar::from_target_isize(-1, this), dest)?;
|
||||
return Ok(());
|
||||
}
|
||||
};
|
||||
|
|
@ -173,7 +173,7 @@ pub fn futex<'tcx>(
|
|||
this.block_thread(thread);
|
||||
this.futex_wait(addr_usize, thread, bitset);
|
||||
// Succesfully waking up from FUTEX_WAIT always returns zero.
|
||||
this.write_scalar(Scalar::from_machine_isize(0, this), dest)?;
|
||||
this.write_scalar(Scalar::from_target_isize(0, this), dest)?;
|
||||
// Register a timeout callback if a timeout was specified.
|
||||
// This callback will override the return value when the timeout triggers.
|
||||
if let Some(timeout_time) = timeout_time {
|
||||
|
|
@ -196,7 +196,7 @@ pub fn futex<'tcx>(
|
|||
this.futex_remove_waiter(self.addr_usize, self.thread);
|
||||
let etimedout = this.eval_libc("ETIMEDOUT");
|
||||
this.set_last_error(etimedout)?;
|
||||
this.write_scalar(Scalar::from_machine_isize(-1, this), &self.dest)?;
|
||||
this.write_scalar(Scalar::from_target_isize(-1, this), &self.dest)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
@ -213,7 +213,7 @@ pub fn futex<'tcx>(
|
|||
// right away without sleeping: -1 and errno set to EAGAIN.
|
||||
let eagain = this.eval_libc("EAGAIN");
|
||||
this.set_last_error(eagain)?;
|
||||
this.write_scalar(Scalar::from_machine_isize(-1, this), dest)?;
|
||||
this.write_scalar(Scalar::from_target_isize(-1, this), dest)?;
|
||||
}
|
||||
}
|
||||
// FUTEX_WAKE: (int *addr, int op = FUTEX_WAKE, int val)
|
||||
|
|
@ -239,7 +239,7 @@ pub fn futex<'tcx>(
|
|||
if bitset == 0 {
|
||||
let einval = this.eval_libc("EINVAL");
|
||||
this.set_last_error(einval)?;
|
||||
this.write_scalar(Scalar::from_machine_isize(-1, this), dest)?;
|
||||
this.write_scalar(Scalar::from_target_isize(-1, this), dest)?;
|
||||
return Ok(());
|
||||
}
|
||||
// Together with the SeqCst fence in futex_wait, this makes sure that futex_wait
|
||||
|
|
@ -257,7 +257,7 @@ pub fn futex<'tcx>(
|
|||
break;
|
||||
}
|
||||
}
|
||||
this.write_scalar(Scalar::from_machine_isize(n, this), dest)?;
|
||||
this.write_scalar(Scalar::from_target_isize(n, this), dest)?;
|
||||
}
|
||||
op => throw_unsup_format!("Miri does not support `futex` syscall with op={}", op),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
Dlsym::getentropy => {
|
||||
let [ptr, len] = check_arg_count(args)?;
|
||||
let ptr = this.read_pointer(ptr)?;
|
||||
let len = this.read_machine_usize(len)?;
|
||||
let len = this.read_target_usize(len)?;
|
||||
this.gen_random(ptr, len)?;
|
||||
this.write_null(dest)?;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -161,13 +161,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
// Querying system information
|
||||
"pthread_get_stackaddr_np" => {
|
||||
let [thread] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
||||
this.read_machine_usize(thread)?;
|
||||
this.read_target_usize(thread)?;
|
||||
let stack_addr = Scalar::from_uint(this.machine.stack_addr, this.pointer_size());
|
||||
this.write_scalar(stack_addr, dest)?;
|
||||
}
|
||||
"pthread_get_stacksize_np" => {
|
||||
let [thread] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
||||
this.read_machine_usize(thread)?;
|
||||
this.read_target_usize(thread)?;
|
||||
let stack_size = Scalar::from_uint(this.machine.stack_size, this.pointer_size());
|
||||
this.write_scalar(stack_size, dest)?;
|
||||
}
|
||||
|
|
@ -176,7 +176,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
"pthread_setname_np" => {
|
||||
let [name] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
||||
let thread = this.pthread_self()?;
|
||||
let max_len = this.eval_libc("MAXTHREADNAMESIZE").to_machine_usize(this)?;
|
||||
let max_len = this.eval_libc("MAXTHREADNAMESIZE").to_target_usize(this)?;
|
||||
let res = this.pthread_setname_np(
|
||||
thread,
|
||||
this.read_scalar(name)?,
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
throw_unsup_format!("Miri supports pthread_join only with retval==NULL");
|
||||
}
|
||||
|
||||
let thread_id = this.read_machine_usize(thread)?;
|
||||
let thread_id = this.read_target_usize(thread)?;
|
||||
this.join_thread_exclusive(thread_id.try_into().expect("thread ID should fit in u32"))?;
|
||||
|
||||
Ok(0)
|
||||
|
|
@ -51,7 +51,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
fn pthread_detach(&mut self, thread: &OpTy<'tcx, Provenance>) -> InterpResult<'tcx, i32> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
let thread_id = this.read_machine_usize(thread)?;
|
||||
let thread_id = this.read_target_usize(thread)?;
|
||||
this.detach_thread(
|
||||
thread_id.try_into().expect("thread ID should fit in u32"),
|
||||
/*allow_terminated_joined*/ false,
|
||||
|
|
@ -64,7 +64,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
let this = self.eval_context_mut();
|
||||
|
||||
let thread_id = this.get_active_thread();
|
||||
Ok(Scalar::from_machine_usize(thread_id.into(), this))
|
||||
Ok(Scalar::from_target_usize(thread_id.into(), this))
|
||||
}
|
||||
|
||||
/// Set the name of the current thread. `max_name_len` is the maximal length of the name
|
||||
|
|
@ -77,7 +77,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
) -> InterpResult<'tcx, Scalar<Provenance>> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
let thread = ThreadId::try_from(thread.to_machine_usize(this)?).unwrap();
|
||||
let thread = ThreadId::try_from(thread.to_target_usize(this)?).unwrap();
|
||||
let name = name.to_pointer(this)?;
|
||||
|
||||
let name = this.read_c_str(name)?.to_owned();
|
||||
|
|
@ -100,9 +100,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
) -> InterpResult<'tcx, Scalar<Provenance>> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
let thread = ThreadId::try_from(thread.to_machine_usize(this)?).unwrap();
|
||||
let thread = ThreadId::try_from(thread.to_target_usize(this)?).unwrap();
|
||||
let name_out = name_out.to_pointer(this)?;
|
||||
let len = len.to_machine_usize(this)?;
|
||||
let len = len.to_target_usize(this)?;
|
||||
|
||||
let name = this.get_thread_name(thread).to_owned();
|
||||
let (success, _written) = this.write_c_str(&name, name_out, len)?;
|
||||
|
|
|
|||
|
|
@ -67,10 +67,10 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
byte_offset,
|
||||
_key,
|
||||
] = check_arg_count(args)?;
|
||||
let handle = this.read_machine_isize(handle)?;
|
||||
let handle = this.read_target_isize(handle)?;
|
||||
let buf = this.read_pointer(buf)?;
|
||||
let n = this.read_scalar(n)?.to_u32()?;
|
||||
let byte_offset = this.read_machine_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.deref_operand(io_status_block)?;
|
||||
|
||||
if byte_offset != 0 {
|
||||
|
|
@ -104,7 +104,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
let io_status_information =
|
||||
this.mplace_field_named(&io_status_block, "Information")?;
|
||||
this.write_scalar(
|
||||
Scalar::from_machine_usize(n.into(), this),
|
||||
Scalar::from_target_usize(n.into(), this),
|
||||
&io_status_information.into(),
|
||||
)?;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -73,9 +73,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
"HeapAlloc" => {
|
||||
let [handle, flags, size] =
|
||||
this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
|
||||
this.read_machine_isize(handle)?;
|
||||
this.read_target_isize(handle)?;
|
||||
let flags = this.read_scalar(flags)?.to_u32()?;
|
||||
let size = this.read_machine_usize(size)?;
|
||||
let size = this.read_target_usize(size)?;
|
||||
let heap_zero_memory = 0x00000008; // HEAP_ZERO_MEMORY
|
||||
let zero_init = (flags & heap_zero_memory) == heap_zero_memory;
|
||||
let res = this.malloc(size, zero_init, MiriMemoryKind::WinHeap)?;
|
||||
|
|
@ -84,7 +84,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
"HeapFree" => {
|
||||
let [handle, flags, ptr] =
|
||||
this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
|
||||
this.read_machine_isize(handle)?;
|
||||
this.read_target_isize(handle)?;
|
||||
this.read_scalar(flags)?.to_u32()?;
|
||||
let ptr = this.read_pointer(ptr)?;
|
||||
this.free(ptr, MiriMemoryKind::WinHeap)?;
|
||||
|
|
@ -93,10 +93,10 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
"HeapReAlloc" => {
|
||||
let [handle, flags, ptr, size] =
|
||||
this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
|
||||
this.read_machine_isize(handle)?;
|
||||
this.read_target_isize(handle)?;
|
||||
this.read_scalar(flags)?.to_u32()?;
|
||||
let ptr = this.read_pointer(ptr)?;
|
||||
let size = this.read_machine_usize(size)?;
|
||||
let size = this.read_target_usize(size)?;
|
||||
let res = this.realloc(ptr, size, MiriMemoryKind::WinHeap)?;
|
||||
this.write_pointer(res, dest)?;
|
||||
}
|
||||
|
|
@ -299,7 +299,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
#[allow(non_snake_case)]
|
||||
let [hModule, lpProcName] =
|
||||
this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
|
||||
this.read_machine_isize(hModule)?;
|
||||
this.read_target_isize(hModule)?;
|
||||
let name = this.read_c_str(this.read_pointer(lpProcName)?)?;
|
||||
if let Some(dlsym) = Dlsym::from_str(name, &this.tcx.sess.target.os)? {
|
||||
let ptr = this.create_fn_alloc_ptr(FnVal::Other(dlsym));
|
||||
|
|
@ -323,7 +323,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
let [algorithm, ptr, len, flags] =
|
||||
this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
|
||||
let algorithm = this.read_scalar(algorithm)?;
|
||||
let algorithm = algorithm.to_machine_usize(this)?;
|
||||
let algorithm = algorithm.to_target_usize(this)?;
|
||||
let ptr = this.read_pointer(ptr)?;
|
||||
let len = this.read_scalar(len)?.to_u32()?;
|
||||
let flags = this.read_scalar(flags)?.to_u32()?;
|
||||
|
|
@ -357,7 +357,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
// `term` needs this, so we fake it.
|
||||
let [console, buffer_info] =
|
||||
this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
|
||||
this.read_machine_isize(console)?;
|
||||
this.read_target_isize(console)?;
|
||||
this.deref_operand(buffer_info)?;
|
||||
// Indicate an error.
|
||||
// FIXME: we should set last_error, but to what?
|
||||
|
|
@ -371,7 +371,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
// one it is. This is very fake, but libtest needs it so we cannot make it a
|
||||
// std-only shim.
|
||||
// FIXME: this should return real HANDLEs when io support is added
|
||||
this.write_scalar(Scalar::from_machine_isize(which.into(), this), dest)?;
|
||||
this.write_scalar(Scalar::from_target_isize(which.into(), this), dest)?;
|
||||
}
|
||||
"CloseHandle" => {
|
||||
let [handle] =
|
||||
|
|
@ -386,7 +386,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
|
||||
this.check_no_isolation("`GetModuleFileNameW`")?;
|
||||
|
||||
let handle = this.read_machine_usize(handle)?;
|
||||
let handle = this.read_target_usize(handle)?;
|
||||
let filename = this.read_pointer(filename)?;
|
||||
let size = this.read_scalar(size)?.to_u32()?;
|
||||
|
||||
|
|
@ -473,7 +473,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
"GetConsoleMode" if this.frame_in_std() => {
|
||||
let [console, mode] =
|
||||
this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
|
||||
this.read_machine_isize(console)?;
|
||||
this.read_target_isize(console)?;
|
||||
this.deref_operand(mode)?;
|
||||
// Indicate an error.
|
||||
this.write_null(dest)?;
|
||||
|
|
|
|||
|
|
@ -124,14 +124,14 @@ impl Handle {
|
|||
// see https://docs.microsoft.com/en-us/windows/win32/winprog64/interprocess-communication
|
||||
#[allow(clippy::cast_possible_wrap)] // we want it to wrap
|
||||
let signed_handle = self.to_packed() as i32;
|
||||
Scalar::from_machine_isize(signed_handle.into(), cx)
|
||||
Scalar::from_target_isize(signed_handle.into(), cx)
|
||||
}
|
||||
|
||||
pub fn from_scalar<'tcx>(
|
||||
handle: Scalar<Provenance>,
|
||||
cx: &impl HasDataLayout,
|
||||
) -> InterpResult<'tcx, Option<Self>> {
|
||||
let sign_extended_handle = handle.to_machine_isize(cx)?;
|
||||
let sign_extended_handle = handle.to_target_isize(cx)?;
|
||||
|
||||
#[allow(clippy::cast_sign_loss)] // we want to lose the sign
|
||||
let handle = if let Ok(signed_handle) = i32::try_from(sign_extended_handle) {
|
||||
|
|
|
|||
|
|
@ -273,7 +273,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
|
||||
let ptr = this.read_pointer(ptr_op)?;
|
||||
let compare = this.read_pointer(compare_op)?;
|
||||
let size = this.read_machine_usize(size_op)?;
|
||||
let size = this.read_target_usize(size_op)?;
|
||||
let timeout_ms = this.read_scalar(timeout_op)?.to_u32()?;
|
||||
|
||||
let thread = this.get_active_thread();
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
|
||||
let security = this.read_pointer(security_op)?;
|
||||
// stacksize is ignored, but still needs to be a valid usize
|
||||
this.read_machine_usize(stacksize_op)?;
|
||||
this.read_target_usize(stacksize_op)?;
|
||||
let start_routine = this.read_pointer(start_op)?;
|
||||
let func_arg = this.read_immediate(arg_op)?;
|
||||
let flags = this.read_scalar(flags_op)?.to_u32()?;
|
||||
|
|
|
|||
|
|
@ -192,8 +192,6 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
|
|||
"regex-automata",
|
||||
"regex-syntax",
|
||||
"remove_dir_all",
|
||||
"rls-data",
|
||||
"rls-span",
|
||||
"rustc-demangle",
|
||||
"rustc-hash",
|
||||
"rustc-rayon",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "x"
|
||||
version = "0.1.0"
|
||||
version = "0.1.1"
|
||||
description = "Run x.py slightly more conveniently"
|
||||
edition = "2021"
|
||||
publish = false
|
||||
|
|
|
|||
|
|
@ -9,11 +9,47 @@
|
|||
//! We also don't use `pwsh` on Windows, because it is not installed by default;
|
||||
|
||||
use std::{
|
||||
env, io,
|
||||
env::{self, consts::EXE_EXTENSION},
|
||||
io,
|
||||
path::Path,
|
||||
process::{self, Command, ExitStatus},
|
||||
};
|
||||
|
||||
const PYTHON: &str = "python";
|
||||
const PYTHON2: &str = "python2";
|
||||
const PYTHON3: &str = "python3";
|
||||
|
||||
fn python() -> &'static str {
|
||||
let val = match env::var_os("PATH") {
|
||||
Some(val) => val,
|
||||
None => return PYTHON,
|
||||
};
|
||||
|
||||
let mut python2 = false;
|
||||
let mut python3 = false;
|
||||
|
||||
for dir in env::split_paths(&val) {
|
||||
// `python` should always take precedence over python2 / python3 if it exists
|
||||
if dir.join(PYTHON).with_extension(EXE_EXTENSION).exists() {
|
||||
return PYTHON;
|
||||
}
|
||||
|
||||
python2 |= dir.join(PYTHON2).with_extension(EXE_EXTENSION).exists();
|
||||
python3 |= dir.join(PYTHON3).with_extension(EXE_EXTENSION).exists();
|
||||
}
|
||||
|
||||
// try 3 before 2
|
||||
if python3 {
|
||||
PYTHON3
|
||||
} else if python2 {
|
||||
PYTHON2
|
||||
} else {
|
||||
// Python was not found on path, so exit
|
||||
eprintln!("Unable to find python in your PATH. Please check it is installed.");
|
||||
process::exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn x_command(dir: &Path) -> Command {
|
||||
let mut cmd = Command::new("powershell.exe");
|
||||
|
|
@ -51,6 +87,17 @@ fn exec_or_status(command: &mut Command) -> io::Result<ExitStatus> {
|
|||
command.status()
|
||||
}
|
||||
|
||||
fn handle_result(result: io::Result<ExitStatus>, cmd: Command) {
|
||||
match result {
|
||||
Err(error) => {
|
||||
eprintln!("Failed to invoke `{:?}`: {}", cmd, error);
|
||||
}
|
||||
Ok(status) => {
|
||||
process::exit(status.code().unwrap_or(1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
match env::args().skip(1).next().as_deref() {
|
||||
Some("--wrapper-version") => {
|
||||
|
|
@ -70,22 +117,19 @@ fn main() {
|
|||
|
||||
for dir in current.ancestors() {
|
||||
let candidate = dir.join("x.py");
|
||||
|
||||
if candidate.exists() {
|
||||
let mut cmd = x_command(dir);
|
||||
|
||||
cmd.args(env::args().skip(1)).current_dir(dir);
|
||||
|
||||
let result = exec_or_status(&mut cmd);
|
||||
|
||||
match result {
|
||||
Err(error) => {
|
||||
eprintln!("Failed to invoke `{:?}`: {}", cmd, error);
|
||||
}
|
||||
Ok(status) => {
|
||||
process::exit(status.code().unwrap_or(1));
|
||||
}
|
||||
let shell_script_candidate = dir.join("x");
|
||||
let mut cmd: Command;
|
||||
if shell_script_candidate.exists() {
|
||||
cmd = x_command(dir);
|
||||
cmd.args(env::args().skip(1)).current_dir(dir);
|
||||
} else {
|
||||
// For older checkouts that do not have the x shell script, default to python
|
||||
cmd = Command::new(python());
|
||||
cmd.arg(&candidate).args(env::args().skip(1)).current_dir(dir);
|
||||
}
|
||||
let result = exec_or_status(&mut cmd);
|
||||
handle_result(result, cmd);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue