Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Miri subtree update #120451

Merged
merged 44 commits into from
Jan 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
9911d8d
freebsd add *stat calls interception support
devnexen Nov 20, 2023
006ea03
another trophy
RalfJung Dec 21, 2023
4744336
Run the tier 2 sysroots job on a schedule, not push
saethlin Jan 8, 2024
707db44
Auto merge of #3262 - saethlin:tier-2-cron, r=saethlin
bors Jan 8, 2024
7a75766
Preparing for merge from rustc
Jan 10, 2024
7e9da57
Merge from rustc
Jan 10, 2024
2dc23e7
Auto merge of #3263 - rust-lang:rustup-2024-01-10, r=saethlin
bors Jan 10, 2024
b0dc543
Preparing for merge from rustc
Jan 11, 2024
2a5ae9f
Merge from rustc
Jan 11, 2024
67659fb
Auto merge of #3264 - rust-lang:rustup-2024-01-11, r=saethlin
bors Jan 11, 2024
8619048
Preparing for merge from rustc
Jan 13, 2024
9b46f3b
Merge from rustc
Jan 13, 2024
12c0f09
Auto merge of #3265 - rust-lang:rustup-2024-01-13, r=saethlin
bors Jan 13, 2024
d4cb1df
Preparing for merge from rustc
Jan 14, 2024
7e0fb55
Merge from rustc
Jan 14, 2024
6a234be
fmt
Jan 14, 2024
0c8e1e6
Auto merge of #3267 - rust-lang:rustup-2024-01-14, r=saethlin
bors Jan 14, 2024
384b2ab
Preparing for merge from rustc
Jan 21, 2024
3c055f7
Merge from rustc
Jan 21, 2024
7092c66
update lockfile
RalfJung Jan 21, 2024
70e720b
Auto merge of #3270 - rust-lang:rustup-2024-01-21, r=RalfJung
bors Jan 21, 2024
80874d3
update comment about CARGO_MAKEFLAGS
RalfJung Jan 22, 2024
3d63f42
Auto merge of #3272 - RalfJung:jobserver, r=RalfJung
bors Jan 22, 2024
1806bc9
Preparing for merge from rustc
Jan 23, 2024
cc08dd1
Merge from rustc
Jan 23, 2024
b5a3acf
Auto merge of #3273 - rust-lang:rustup-2024-01-23, r=RalfJung
bors Jan 23, 2024
ef454c4
Preparing for merge from rustc
Jan 24, 2024
dbe1c58
Merge from rustc
Jan 24, 2024
a9bc7e9
disable freeBSD tests for now
RalfJung Jan 24, 2024
cf22ee0
Auto merge of #3275 - rust-lang:rustup-2024-01-24, r=RalfJung
bors Jan 24, 2024
cba1fdb
refactor extern static handling
RalfJung Jan 24, 2024
e611211
add __cxa_thread_atexit_impl on freebsd
RalfJung Jan 24, 2024
12dd3bf
a bit of refactoring for find_mir_or_eval_fn
RalfJung Jan 24, 2024
4e8ad10
Auto merge of #3277 - RalfJung:freebsd, r=RalfJung
bors Jan 24, 2024
9f4d1a4
Auto merge of #3233 - RalfJung:trophy, r=RalfJung
bors Jan 25, 2024
88e1620
Preparing for merge from rustc
Jan 26, 2024
b07da71
Merge from rustc
Jan 26, 2024
b8246e3
fmt
Jan 26, 2024
2318b08
alidate the operand passed to is_val_statically_known
RalfJung Jan 26, 2024
fae15df
Auto merge of #3280 - rust-lang:rustup-2024-01-26, r=RalfJung
bors Jan 26, 2024
3cc0f02
fix typo in operator.rs
RalfJung Jan 27, 2024
0186c24
Auto merge of #3281 - RalfJung:typo, r=RalfJung
bors Jan 27, 2024
8302e25
tweak comments
RalfJung Jan 28, 2024
71f8f49
Auto merge of #3181 - devnexen:stat_calls_fbsd, r=RalfJung
bors Jan 28, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/tools/miri/.github/workflows/sysroots.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
name: Tier 2 sysroots

on: push
# schedule:
# - cron: '44 4 * * *' # At 4:44 UTC every day.
on:
schedule:
- cron: '44 4 * * *' # At 4:44 UTC every day.

defaults:
run:
Expand Down
4 changes: 2 additions & 2 deletions src/tools/miri/Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -486,9 +486,9 @@ checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"

[[package]]
name = "measureme"
version = "10.1.2"
version = "11.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "45e381dcdad44c3c435f8052b08c5c4a1449c48ab56f312345eae12d7a693dbe"
checksum = "dfa4a40f09af7aa6faef38285402a78847d0d72bf8827006cd2a332e1e6e4a8d"
dependencies = [
"log",
"memmap2",
Expand Down
1 change: 1 addition & 0 deletions src/tools/miri/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -590,6 +590,7 @@ Definite bugs found:
* [Incorrect use of `compare_exchange_weak` in `once_cell`](https://github.com/matklad/once_cell/issues/186)
* [Dropping with unaligned pointers in `vec::IntoIter`](https://github.com/rust-lang/rust/pull/106084)
* [Deallocating with the wrong layout in new specializations for in-place `Iterator::collect`](https://github.com/rust-lang/rust/pull/118460)
* [Incorrect offset computation for highly-aligned types in `portable-atomic-util`](https://github.com/taiki-e/portable-atomic/pull/138)

Violations of [Stacked Borrows] found that are likely bugs (but Stacked Borrows is currently just an experiment):

Expand Down
9 changes: 4 additions & 5 deletions src/tools/miri/cargo-miri/src/phases.rs
Original file line number Diff line number Diff line change
Expand Up @@ -501,11 +501,10 @@ pub fn phase_runner(mut binary_args: impl Iterator<Item = String>, phase: Runner
// Set missing env vars. We prefer build-time env vars over run-time ones; see
// <https://github.com/rust-lang/miri/issues/1661> for the kind of issue that fixes.
for (name, val) in info.env {
// `CARGO_MAKEFLAGS` contains information about how to reach the
// jobserver, but by the time the program is being run, that jobserver
// no longer exists. Hence we shouldn't forward this.
// FIXME: Miri builds the final crate without a jobserver.
// This may be fixed with github.com/rust-lang/cargo/issues/12597.
// `CARGO_MAKEFLAGS` contains information about how to reach the jobserver, but by the time
// the program is being run, that jobserver no longer exists (cargo only runs the jobserver
// for the build portion of `cargo run`/`cargo test`). Hence we shouldn't forward this.
// Also see <https://github.com/rust-lang/rust/pull/113730>.
if name == "CARGO_MAKEFLAGS" {
continue;
}
Expand Down
2 changes: 1 addition & 1 deletion src/tools/miri/rust-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
5bcd86d89b2b7b6a490f7e075dd4eb346deb5f98
dd2559e08e1530806740931037d6bb83ef956161
19 changes: 17 additions & 2 deletions src/tools/miri/src/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {

/// Helper function to get a `windows` constant as a `Scalar`.
fn eval_windows(&self, module: &str, name: &str) -> Scalar<Provenance> {
self.eval_context_ref().eval_path_scalar(&["std", "sys", "pal","windows", module, name])
self.eval_context_ref().eval_path_scalar(&["std", "sys", "pal", "windows", module, name])
}

/// Helper function to get a `windows` constant as a `u32`.
Expand Down Expand Up @@ -249,7 +249,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
fn windows_ty_layout(&self, name: &str) -> TyAndLayout<'tcx> {
let this = self.eval_context_ref();
let ty = this
.resolve_path(&["std", "sys", "pal","windows", "c", name], Namespace::TypeNS)
.resolve_path(&["std", "sys", "pal", "windows", "c", name], Namespace::TypeNS)
.ty(*this.tcx, ty::ParamEnv::reveal_all());
this.layout_of(ty).unwrap()
}
Expand All @@ -270,6 +270,21 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
bug!("No field named {} in type {}", name, base.layout().ty);
}

/// Search if `base` (which must be a struct or union type) contains the `name` field.
fn projectable_has_field<P: Projectable<'tcx, Provenance>>(
&self,
base: &P,
name: &str,
) -> bool {
let adt = base.layout().ty.ty_adt_def().unwrap();
for field in adt.non_enum_variant().fields.iter() {
if field.name.as_str() == name {
return true;
}
}
false
}

/// Write an int of the appropriate size to `dest`. The target type may be signed or unsigned,
/// we try to do the right thing anyway. `i128` can fit all integer types except for `u128` so
/// this method is fine for almost all integer types.
Expand Down
1 change: 0 additions & 1 deletion src/tools/miri/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,6 @@ pub use crate::shims::os_str::EvalContextExt as _;
pub use crate::shims::panic::{CatchUnwindData, EvalContextExt as _};
pub use crate::shims::time::EvalContextExt as _;
pub use crate::shims::tls::TlsData;
pub use crate::shims::EvalContextExt as _;

pub use crate::borrow_tracker::stacked_borrows::{
EvalContextExt as _, Item, Permission, Stack, Stacks,
Expand Down
95 changes: 21 additions & 74 deletions src/tools/miri/src/machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ use std::process;

use either::Either;
use rand::rngs::StdRng;
use rand::SeedableRng;
use rand::Rng;
use rand::SeedableRng;

use rustc_ast::ast::Mutability;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
Expand Down Expand Up @@ -83,7 +83,8 @@ pub struct FrameExtra<'tcx> {
impl<'tcx> std::fmt::Debug for FrameExtra<'tcx> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
// Omitting `timing`, it does not support `Debug`.
let FrameExtra { borrow_tracker, catch_unwind, timing: _, is_user_relevant: _, salt: _ } = self;
let FrameExtra { borrow_tracker, catch_unwind, timing: _, is_user_relevant: _, salt: _ } =
self;
f.debug_struct("FrameData")
.field("borrow_tracker", borrow_tracker)
.field("catch_unwind", catch_unwind)
Expand All @@ -93,7 +94,8 @@ impl<'tcx> std::fmt::Debug for FrameExtra<'tcx> {

impl VisitProvenance for FrameExtra<'_> {
fn visit_provenance(&self, visit: &mut VisitWith<'_>) {
let FrameExtra { catch_unwind, borrow_tracker, timing: _, is_user_relevant: _, salt: _ } = self;
let FrameExtra { catch_unwind, borrow_tracker, timing: _, is_user_relevant: _, salt: _ } =
self;

catch_unwind.visit_provenance(visit);
borrow_tracker.visit_provenance(visit);
Expand Down Expand Up @@ -710,7 +712,7 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> {
Ok(())
}

fn add_extern_static(
pub(crate) fn add_extern_static(
this: &mut MiriInterpCx<'mir, 'tcx>,
name: &str,
ptr: Pointer<Option<Provenance>>,
Expand All @@ -720,75 +722,6 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> {
this.machine.extern_statics.try_insert(Symbol::intern(name), ptr).unwrap();
}

fn alloc_extern_static(
this: &mut MiriInterpCx<'mir, 'tcx>,
name: &str,
val: ImmTy<'tcx, Provenance>,
) -> InterpResult<'tcx> {
let place = this.allocate(val.layout, MiriMemoryKind::ExternStatic.into())?;
this.write_immediate(*val, &place)?;
Self::add_extern_static(this, name, place.ptr());
Ok(())
}

/// Sets up the "extern statics" for this machine.
fn init_extern_statics(this: &mut MiriInterpCx<'mir, 'tcx>) -> InterpResult<'tcx> {
// "__rust_no_alloc_shim_is_unstable"
let val = ImmTy::from_int(0, this.machine.layouts.u8);
Self::alloc_extern_static(this, "__rust_no_alloc_shim_is_unstable", val)?;

match this.tcx.sess.target.os.as_ref() {
"linux" => {
// "environ"
Self::add_extern_static(
this,
"environ",
this.machine.env_vars.environ.as_ref().unwrap().ptr(),
);
// A couple zero-initialized pointer-sized extern statics.
// Most of them are for weak symbols, which we all set to null (indicating that the
// symbol is not supported, and triggering fallback code which ends up calling a
// syscall that we do support).
for name in &["__cxa_thread_atexit_impl", "getrandom", "statx", "__clock_gettime64"]
{
let val = ImmTy::from_int(0, this.machine.layouts.usize);
Self::alloc_extern_static(this, name, val)?;
}
}
"freebsd" => {
// "environ"
Self::add_extern_static(
this,
"environ",
this.machine.env_vars.environ.as_ref().unwrap().ptr(),
);
}
"android" => {
// "signal" -- just needs a non-zero pointer value (function does not even get called),
// but we arrange for this to be callable anyway (it will then do nothing).
let layout = this.machine.layouts.const_raw_ptr;
let ptr = this.fn_ptr(FnVal::Other(DynSym::from_str("signal")));
let val = ImmTy::from_scalar(Scalar::from_pointer(ptr, this), layout);
Self::alloc_extern_static(this, "signal", val)?;
// A couple zero-initialized pointer-sized extern statics.
// Most of them are for weak symbols, which we all set to null (indicating that the
// symbol is not supported, and triggering fallback code.)
for name in &["bsd_signal"] {
let val = ImmTy::from_int(0, this.machine.layouts.usize);
Self::alloc_extern_static(this, name, val)?;
}
}
"windows" => {
// "_tls_used"
// This is some obscure hack that is part of the Windows TLS story. It's a `u8`.
let val = ImmTy::from_int(0, this.machine.layouts.u8);
Self::alloc_extern_static(this, "_tls_used", val)?;
}
_ => {} // No "extern statics" supported on this target
}
Ok(())
}

pub(crate) fn communicate(&self) -> bool {
self.isolated_op == IsolatedOp::Allow
}
Expand Down Expand Up @@ -1009,7 +942,21 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
ret: Option<mir::BasicBlock>,
unwind: mir::UnwindAction,
) -> InterpResult<'tcx, Option<(&'mir mir::Body<'tcx>, ty::Instance<'tcx>)>> {
ecx.find_mir_or_eval_fn(instance, abi, args, dest, ret, unwind)
// For foreign items, try to see if we can emulate them.
if ecx.tcx.is_foreign_item(instance.def_id()) {
// An external function call that does not have a MIR body. We either find MIR elsewhere
// or emulate its effect.
// This will be Ok(None) if we're emulating the intrinsic entirely within Miri (no need
// to run extra MIR), and Ok(Some(body)) if we found MIR to run for the
// foreign function
// Any needed call to `goto_block` will be performed by `emulate_foreign_item`.
let args = ecx.copy_fn_args(args)?; // FIXME: Should `InPlace` arguments be reset to uninit?
let link_name = ecx.item_link_name(instance.def_id());
return ecx.emulate_foreign_item(link_name, abi, &args, dest, ret, unwind);
}

// Otherwise, load the MIR.
Ok(Some((ecx.load_mir(instance.def, None)?, instance)))
}

#[inline(always)]
Expand Down
2 changes: 1 addition & 1 deletion src/tools/miri/src/operator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {

Ok(match bin_op {
Eq | Ne | Lt | Le | Gt | Ge => {
assert_eq!(left.layout.abi, right.layout.abi); // types an differ, e.g. fn ptrs with different `for`
assert_eq!(left.layout.abi, right.layout.abi); // types can differ, e.g. fn ptrs with different `for`
let size = this.pointer_size();
// Just compare the bits. ScalarPairs are compared lexicographically.
// We thus always compare pairs and simply fill scalars up with 0.
Expand Down
79 changes: 79 additions & 0 deletions src/tools/miri/src/shims/extern_static.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
//! Provides the `extern static` that this platform expects.

use crate::*;

impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> {
fn alloc_extern_static(
this: &mut MiriInterpCx<'mir, 'tcx>,
name: &str,
val: ImmTy<'tcx, Provenance>,
) -> InterpResult<'tcx> {
let place = this.allocate(val.layout, MiriMemoryKind::ExternStatic.into())?;
this.write_immediate(*val, &place)?;
Self::add_extern_static(this, name, place.ptr());
Ok(())
}

/// Zero-initialized pointer-sized extern statics are pretty common.
/// Most of them are for weak symbols, which we all set to null (indicating that the
/// symbol is not supported, and triggering fallback code which ends up calling a
/// syscall that we do support).
fn null_ptr_extern_statics(
this: &mut MiriInterpCx<'mir, 'tcx>,
names: &[&str],
) -> InterpResult<'tcx> {
for name in names {
let val = ImmTy::from_int(0, this.machine.layouts.usize);
Self::alloc_extern_static(this, name, val)?;
}
Ok(())
}

/// Sets up the "extern statics" for this machine.
pub fn init_extern_statics(this: &mut MiriInterpCx<'mir, 'tcx>) -> InterpResult<'tcx> {
// "__rust_no_alloc_shim_is_unstable"
let val = ImmTy::from_int(0, this.machine.layouts.u8);
Self::alloc_extern_static(this, "__rust_no_alloc_shim_is_unstable", val)?;

match this.tcx.sess.target.os.as_ref() {
"linux" => {
Self::null_ptr_extern_statics(
this,
&["__cxa_thread_atexit_impl", "getrandom", "statx", "__clock_gettime64"],
)?;
// "environ"
Self::add_extern_static(
this,
"environ",
this.machine.env_vars.environ.as_ref().unwrap().ptr(),
);
}
"freebsd" => {
Self::null_ptr_extern_statics(this, &["__cxa_thread_atexit_impl"])?;
// "environ"
Self::add_extern_static(
this,
"environ",
this.machine.env_vars.environ.as_ref().unwrap().ptr(),
);
}
"android" => {
Self::null_ptr_extern_statics(this, &["bsd_signal"])?;
// "signal" -- just needs a non-zero pointer value (function does not even get called),
// but we arrange for this to call the `signal` function anyway.
let layout = this.machine.layouts.const_raw_ptr;
let ptr = this.fn_ptr(FnVal::Other(DynSym::from_str("signal")));
let val = ImmTy::from_scalar(Scalar::from_pointer(ptr, this), layout);
Self::alloc_extern_static(this, "signal", val)?;
}
"windows" => {
// "_tls_used"
// This is some obscure hack that is part of the Windows TLS story. It's a `u8`.
let val = ImmTy::from_int(0, this.machine.layouts.u8);
Self::alloc_extern_static(this, "_tls_used", val)?;
}
_ => {} // No "extern statics" supported on this target
}
Ok(())
}
}
3 changes: 2 additions & 1 deletion src/tools/miri/src/shims/intrinsics/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
// ```
// Would not be considered UB, or the other way around (`is_val_statically_known(0)`).
"is_val_statically_known" => {
let [_] = check_arg_count(args)?;
let [arg] = check_arg_count(args)?;
this.validate_operand(arg)?;
let branch: bool = this.machine.rng.get_mut().gen();
this.write_scalar(Scalar::from_bool(branch), dest)?;
}
Expand Down
42 changes: 1 addition & 41 deletions src/tools/miri/src/shims/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,48 +10,8 @@ pub mod windows;
mod x86;

pub mod env;
pub mod extern_static;
pub mod os_str;
pub mod panic;
pub mod time;
pub mod tls;

// End module management, begin local code

use log::trace;

use rustc_middle::{mir, ty};
use rustc_target::spec::abi::Abi;

use crate::*;

impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {}
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
fn find_mir_or_eval_fn(
&mut self,
instance: ty::Instance<'tcx>,
abi: Abi,
args: &[FnArg<'tcx, Provenance>],
dest: &PlaceTy<'tcx, Provenance>,
ret: Option<mir::BasicBlock>,
unwind: mir::UnwindAction,
) -> InterpResult<'tcx, Option<(&'mir mir::Body<'tcx>, ty::Instance<'tcx>)>> {
let this = self.eval_context_mut();
trace!("eval_fn_call: {:#?}, {:?}", instance, dest);

// For foreign items, try to see if we can emulate them.
if this.tcx.is_foreign_item(instance.def_id()) {
// An external function call that does not have a MIR body. We either find MIR elsewhere
// or emulate its effect.
// This will be Ok(None) if we're emulating the intrinsic entirely within Miri (no need
// to run extra MIR), and Ok(Some(body)) if we found MIR to run for the
// foreign function
// Any needed call to `goto_block` will be performed by `emulate_foreign_item`.
let args = this.copy_fn_args(args)?; // FIXME: Should `InPlace` arguments be reset to uninit?
let link_name = this.item_link_name(instance.def_id());
return this.emulate_foreign_item(link_name, abi, &args, dest, ret, unwind);
}

// Otherwise, load the MIR.
Ok(Some((this.load_mir(instance.def, None)?, instance)))
}
}
Loading
Loading