Skip to content

Commit 838a18c

Browse files
authored
Rollup merge of rust-lang#147744 - RalfJung:miri, r=RalfJung
miri subtree update Subtree update of `miri` to rust-lang/miri@50ba3a7. Created using https://github.com/rust-lang/josh-sync. r? `@ghost`
2 parents 28b216e + 2f04473 commit 838a18c

File tree

23 files changed

+190
-77
lines changed

23 files changed

+190
-77
lines changed

Cargo.lock

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1164,7 +1164,7 @@ dependencies = [
11641164
"libc",
11651165
"option-ext",
11661166
"redox_users 0.5.2",
1167-
"windows-sys 0.60.2",
1167+
"windows-sys 0.61.2",
11681168
]
11691169

11701170
[[package]]
@@ -2106,19 +2106,19 @@ dependencies = [
21062106

21072107
[[package]]
21082108
name = "libffi"
2109-
version = "4.1.1"
2109+
version = "5.0.0"
21102110
source = "registry+https://github.com/rust-lang/crates.io-index"
2111-
checksum = "e7681c6fab541f799a829e44a445a0666cf8d8a6cfebf89419e6aed52c604e87"
2111+
checksum = "0444124f3ffd67e1b0b0c661a7f81a278a135eb54aaad4078e79fbc8be50c8a5"
21122112
dependencies = [
21132113
"libc",
21142114
"libffi-sys",
21152115
]
21162116

21172117
[[package]]
21182118
name = "libffi-sys"
2119-
version = "3.3.2"
2119+
version = "4.0.0"
21202120
source = "registry+https://github.com/rust-lang/crates.io-index"
2121-
checksum = "7b0d828d367b4450ed08e7d510dc46636cd660055f50d67ac943bfe788767c29"
2121+
checksum = "3d722da8817ea580d0669da6babe2262d7b86a1af1103da24102b8bb9c101ce7"
21222122
dependencies = [
21232123
"cc",
21242124
]
@@ -2374,7 +2374,7 @@ version = "0.6.1"
23742374
source = "registry+https://github.com/rust-lang/crates.io-index"
23752375
checksum = "536bfad37a309d62069485248eeaba1e8d9853aaf951caaeaed0585a95346f08"
23762376
dependencies = [
2377-
"windows-sys 0.60.2",
2377+
"windows-sys 0.61.2",
23782378
]
23792379

23802380
[[package]]

src/tools/miri/Cargo.lock

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -794,19 +794,19 @@ checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776"
794794

795795
[[package]]
796796
name = "libffi"
797-
version = "4.1.1"
797+
version = "5.0.0"
798798
source = "registry+https://github.com/rust-lang/crates.io-index"
799-
checksum = "e7681c6fab541f799a829e44a445a0666cf8d8a6cfebf89419e6aed52c604e87"
799+
checksum = "0444124f3ffd67e1b0b0c661a7f81a278a135eb54aaad4078e79fbc8be50c8a5"
800800
dependencies = [
801801
"libc",
802802
"libffi-sys",
803803
]
804804

805805
[[package]]
806806
name = "libffi-sys"
807-
version = "3.3.2"
807+
version = "4.0.0"
808808
source = "registry+https://github.com/rust-lang/crates.io-index"
809-
checksum = "7b0d828d367b4450ed08e7d510dc46636cd660055f50d67ac943bfe788767c29"
809+
checksum = "3d722da8817ea580d0669da6babe2262d7b86a1af1103da24102b8bb9c101ce7"
810810
dependencies = [
811811
"cc",
812812
]

src/tools/miri/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ features = ['unprefixed_malloc_on_supported_platforms']
3939
[target.'cfg(unix)'.dependencies]
4040
libc = "0.2"
4141
# native-lib dependencies
42-
libffi = { version = "4.1.1", optional = true }
42+
libffi = { version = "5.0.0", optional = true }
4343
libloading = { version = "0.8", optional = true }
4444
serde = { version = "1.0.219", features = ["derive"], optional = true }
4545

src/tools/miri/rust-version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
36e4f5d1fe1d63953a5bf1758ce2b64172623e2e
1+
28d0a4a205f9e511ad2f51ee79a4aa19a704a455

src/tools/miri/src/concurrency/genmc/global_allocations.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use rand::SeedableRng;
66
use rand::rngs::StdRng;
77
use rustc_const_eval::interpret::{AllocId, AllocInfo, InterpResult, interp_ok};
88
use rustc_data_structures::fx::FxHashMap;
9-
use tracing::debug;
9+
use rustc_log::tracing::debug;
1010

1111
use crate::alloc_addresses::AddressGenerator;
1212

src/tools/miri/src/concurrency/genmc/run.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use std::sync::Arc;
33
use std::time::Instant;
44

55
use genmc_sys::EstimationResult;
6+
use rustc_log::tracing;
67
use rustc_middle::ty::TyCtxt;
78

89
use super::GlobalState;

src/tools/miri/src/concurrency/genmc/scheduling.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use genmc_sys::{ActionKind, ExecutionState};
2+
use rustc_data_structures::either::Either;
23
use rustc_middle::mir::TerminatorKind;
34
use rustc_middle::ty::{self, Ty};
45

@@ -38,7 +39,7 @@ fn get_next_instruction_kind<'tcx>(
3839
let Some(frame) = thread_manager.active_thread_stack().last() else {
3940
return interp_ok(NonAtomic);
4041
};
41-
let either::Either::Left(loc) = frame.current_loc() else {
42+
let Either::Left(loc) = frame.current_loc() else {
4243
// We are unwinding, so the next step is definitely not atomic.
4344
return interp_ok(NonAtomic);
4445
};

src/tools/miri/src/diagnostics.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ pub enum NonHaltingDiagnostic {
139139
NativeCallSharedMem {
140140
tracing: bool,
141141
},
142+
NativeCallFnPtr,
142143
WeakMemoryOutdatedLoad {
143144
ptr: Pointer,
144145
},
@@ -644,6 +645,11 @@ impl<'tcx> MiriMachine<'tcx> {
644645
Int2Ptr { .. } => ("integer-to-pointer cast".to_string(), DiagLevel::Warning),
645646
NativeCallSharedMem { .. } =>
646647
("sharing memory with a native function".to_string(), DiagLevel::Warning),
648+
NativeCallFnPtr =>
649+
(
650+
"sharing a function pointer with a native function".to_string(),
651+
DiagLevel::Warning,
652+
),
647653
ExternTypeReborrow =>
648654
("reborrow of reference to `extern type`".to_string(), DiagLevel::Warning),
649655
GenmcCompareExchangeWeak | GenmcCompareExchangeOrderingMismatch { .. } =>
@@ -682,6 +688,8 @@ impl<'tcx> MiriMachine<'tcx> {
682688
Int2Ptr { .. } => format!("integer-to-pointer cast"),
683689
NativeCallSharedMem { .. } =>
684690
format!("sharing memory with a native function called via FFI"),
691+
NativeCallFnPtr =>
692+
format!("sharing a function pointer with a native function called via FFI"),
685693
WeakMemoryOutdatedLoad { ptr } =>
686694
format!("weak memory emulation: outdated value returned from load at {ptr}"),
687695
ExternTypeReborrow =>
@@ -779,6 +787,11 @@ impl<'tcx> MiriMachine<'tcx> {
779787
),
780788
]
781789
},
790+
NativeCallFnPtr => {
791+
vec![note!(
792+
"calling Rust functions from C is not supported and will, in the best case, crash the program"
793+
)]
794+
}
782795
ExternTypeReborrow => {
783796
assert!(self.borrow_tracker.as_ref().is_some_and(|b| {
784797
matches!(

src/tools/miri/src/shims/native_lib/ffi.rs

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,9 @@ use libffi::middle::{Arg as ArgPtr, Cif, Type as FfiType};
99
///
1010
/// The safety invariants of the foreign function being called must be upheld (if any).
1111
pub unsafe fn call<R: libffi::high::CType>(fun: CodePtr, args: &mut [OwnedArg]) -> R {
12-
let arg_ptrs: Vec<_> = args.iter().map(|arg| arg.ptr()).collect();
1312
let cif = Cif::new(args.iter_mut().map(|arg| arg.ty.take().unwrap()), R::reify().into_middle());
14-
// SAFETY: Caller upholds that the function is safe to call, and since we
15-
// were passed a slice reference we know the `OwnedArg`s won't have been
16-
// dropped by this point.
13+
let arg_ptrs: Vec<_> = args.iter().map(|arg| ArgPtr::new(&*arg.bytes)).collect();
14+
// SAFETY: Caller upholds that the function is safe to call.
1715
unsafe { cif.call(fun, &arg_ptrs) }
1816
}
1917

@@ -31,16 +29,4 @@ impl OwnedArg {
3129
pub fn new(ty: FfiType, bytes: Box<[u8]>) -> Self {
3230
Self { ty: Some(ty), bytes }
3331
}
34-
35-
/// Creates a libffi argument pointer pointing to this argument's bytes.
36-
/// NB: Since `libffi::middle::Arg` ignores the lifetime of the reference
37-
/// it's derived from, it is up to the caller to ensure the `OwnedArg` is
38-
/// not dropped before unsafely calling `libffi::middle::Cif::call()`!
39-
fn ptr(&self) -> ArgPtr {
40-
// FIXME: Using `&self.bytes[0]` to reference the whole array is
41-
// definitely unsound under SB, but we're waiting on
42-
// https://github.com/libffi-rs/libffi-rs/commit/112a37b3b6ffb35bd75241fbcc580de40ba74a73
43-
// to land in a release so that we don't need to do this.
44-
ArgPtr::new(&self.bytes[0])
45-
}
4632
}

src/tools/miri/src/shims/native_lib/mod.rs

Lines changed: 41 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use libffi::low::CodePtr;
77
use libffi::middle::Type as FfiType;
88
use rustc_abi::{HasDataLayout, Size};
99
use rustc_data_structures::either;
10-
use rustc_middle::ty::layout::HasTypingEnv;
10+
use rustc_middle::ty::layout::TyAndLayout;
1111
use rustc_middle::ty::{self, IntTy, Ty, UintTy};
1212
use rustc_span::Symbol;
1313
use serde::{Deserialize, Serialize};
@@ -278,7 +278,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
278278

279279
// This should go first so that we emit unsupported before doing a bunch
280280
// of extra work for types that aren't supported yet.
281-
let ty = this.ty_to_ffitype(v.layout.ty)?;
281+
let ty = this.ty_to_ffitype(v.layout)?;
282282

283283
// Helper to print a warning when a pointer is shared with the native code.
284284
let expose = |prov: Provenance| -> InterpResult<'tcx> {
@@ -387,34 +387,44 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
387387
let this = self.eval_context_ref();
388388
let mut fields = vec![];
389389
for field in &adt_def.non_enum_variant().fields {
390-
fields.push(this.ty_to_ffitype(field.ty(*this.tcx, args))?);
390+
let layout = this.layout_of(field.ty(*this.tcx, args))?;
391+
fields.push(this.ty_to_ffitype(layout)?);
391392
}
392393

393394
interp_ok(FfiType::structure(fields))
394395
}
395396

396397
/// Gets the matching libffi type for a given Ty.
397-
fn ty_to_ffitype(&self, ty: Ty<'tcx>) -> InterpResult<'tcx, FfiType> {
398-
let this = self.eval_context_ref();
399-
interp_ok(match ty.kind() {
400-
ty::Int(IntTy::I8) => FfiType::i8(),
401-
ty::Int(IntTy::I16) => FfiType::i16(),
402-
ty::Int(IntTy::I32) => FfiType::i32(),
403-
ty::Int(IntTy::I64) => FfiType::i64(),
404-
ty::Int(IntTy::Isize) => FfiType::isize(),
405-
ty::Uint(UintTy::U8) => FfiType::u8(),
406-
ty::Uint(UintTy::U16) => FfiType::u16(),
407-
ty::Uint(UintTy::U32) => FfiType::u32(),
408-
ty::Uint(UintTy::U64) => FfiType::u64(),
409-
ty::Uint(UintTy::Usize) => FfiType::usize(),
410-
ty::RawPtr(pointee_ty, _mut) => {
411-
if !pointee_ty.is_sized(*this.tcx, this.typing_env()) {
412-
throw_unsup_format!("passing a pointer to an unsized type over FFI: {}", ty);
413-
}
414-
FfiType::pointer()
415-
}
416-
ty::Adt(adt_def, args) => self.adt_to_ffitype(ty, *adt_def, args)?,
417-
_ => throw_unsup_format!("unsupported argument type for native call: {}", ty),
398+
fn ty_to_ffitype(&self, layout: TyAndLayout<'tcx>) -> InterpResult<'tcx, FfiType> {
399+
use rustc_abi::{AddressSpace, BackendRepr, Integer, Primitive};
400+
401+
// `BackendRepr::Scalar` is also a signal to pass this type as a scalar in the ABI. This
402+
// matches what codegen does. This does mean that we support some types whose ABI is not
403+
// stable, but that's fine -- we are anyway quite conservative in native-lib mode.
404+
if let BackendRepr::Scalar(s) = layout.backend_repr {
405+
// Simple sanity-check: this cannot be `repr(C)`.
406+
assert!(!layout.ty.ty_adt_def().is_some_and(|adt| adt.repr().c()));
407+
return interp_ok(match s.primitive() {
408+
Primitive::Int(Integer::I8, /* signed */ true) => FfiType::i8(),
409+
Primitive::Int(Integer::I16, /* signed */ true) => FfiType::i16(),
410+
Primitive::Int(Integer::I32, /* signed */ true) => FfiType::i32(),
411+
Primitive::Int(Integer::I64, /* signed */ true) => FfiType::i64(),
412+
Primitive::Int(Integer::I8, /* signed */ false) => FfiType::u8(),
413+
Primitive::Int(Integer::I16, /* signed */ false) => FfiType::u16(),
414+
Primitive::Int(Integer::I32, /* signed */ false) => FfiType::u32(),
415+
Primitive::Int(Integer::I64, /* signed */ false) => FfiType::u64(),
416+
Primitive::Pointer(AddressSpace::ZERO) => FfiType::pointer(),
417+
_ =>
418+
throw_unsup_format!(
419+
"unsupported scalar argument type for native call: {}",
420+
layout.ty
421+
),
422+
});
423+
}
424+
interp_ok(match layout.ty.kind() {
425+
// Scalar types have already been handled above.
426+
ty::Adt(adt_def, args) => self.adt_to_ffitype(layout.ty, *adt_def, args)?,
427+
_ => throw_unsup_format!("unsupported argument type for native call: {}", layout.ty),
418428
})
419429
}
420430
}
@@ -455,6 +465,13 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
455465
// pointer was passed as argument). Uninitialised memory is left as-is, but any data
456466
// exposed this way is garbage anyway.
457467
this.visit_reachable_allocs(this.exposed_allocs(), |this, alloc_id, info| {
468+
if matches!(info.kind, AllocKind::Function) {
469+
static DEDUP: AtomicBool = AtomicBool::new(false);
470+
if !DEDUP.swap(true, std::sync::atomic::Ordering::Relaxed) {
471+
// Newly set, so first time we get here.
472+
this.emit_diagnostic(NonHaltingDiagnostic::NativeCallFnPtr);
473+
}
474+
}
458475
// If there is no data behind this pointer, skip this.
459476
if !matches!(info.kind, AllocKind::LiveData) {
460477
return interp_ok(());

0 commit comments

Comments
 (0)