Skip to content
Merged

Rustup #5180

Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion rust-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
be8e82435eb04fbe75ed5286b52735366e160bed
48c2cee70232ecc3a6a8e285b2e15620b39f82a7
34 changes: 19 additions & 15 deletions src/machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -575,8 +575,11 @@ pub struct MiriMachine<'tcx> {

/// Mapping extern static names to their pointer.
pub(crate) extern_statics: FxHashMap<Symbol, StrictPointer>,
/// Statics with `import_linkage` have an extra indirection
/// (<https://github.com/rust-lang/rust/issues/156468>) so we keep them in a separate table.
pub(crate) extern_statics_imports: FxHashMap<Symbol, StrictPointer>,
/// A pointer to the allocation we provide for non-existent weak symbols.
pub(crate) missing_weak_symbol: Option<StrictPointer>,
pub(crate) extern_static_weak_import_default: Option<StrictPointer>,

/// The random number generator used for resolving non-determinism.
/// Needs to be queried by ptr_to_int, hence needs interior mutability.
Expand Down Expand Up @@ -780,7 +783,8 @@ impl<'tcx> MiriMachine<'tcx> {
backtrace_style: config.backtrace_style,
user_relevant_crates,
extern_statics: FxHashMap::default(),
missing_weak_symbol: None,
extern_statics_imports: FxHashMap::default(),
extern_static_weak_import_default: None,
rng: RefCell::new(rng),
allocator: (!config.native_lib.is_empty())
.then(|| Rc::new(RefCell::new(crate::alloc::isolated_alloc::IsolatedAlloc::new()))),
Expand Down Expand Up @@ -905,12 +909,6 @@ impl<'tcx> MiriMachine<'tcx> {
interp_ok(())
}

pub(crate) fn add_extern_static(ecx: &mut MiriInterpCx<'tcx>, name: &str, ptr: Pointer) {
// This got just allocated, so there definitely is a pointer here.
let ptr = ptr.into_pointer_or_addr().unwrap();
ecx.machine.extern_statics.try_insert(Symbol::intern(name), ptr).unwrap();
}

pub(crate) fn communicate(&self) -> bool {
self.isolated_op == IsolatedOp::Allow
}
Expand Down Expand Up @@ -1024,7 +1022,8 @@ impl VisitProvenance for MiriMachine<'_> {
argv,
cmd_line,
extern_statics,
missing_weak_symbol,
extern_statics_imports,
extern_static_weak_import_default,
dirs,
borrow_tracker,
data_race,
Expand Down Expand Up @@ -1087,10 +1086,9 @@ impl VisitProvenance for MiriMachine<'_> {
argc.visit_provenance(visit);
argv.visit_provenance(visit);
cmd_line.visit_provenance(visit);
missing_weak_symbol.visit_provenance(visit);
for ptr in extern_statics.values() {
ptr.visit_provenance(visit);
}
extern_static_weak_import_default.visit_provenance(visit);
extern_statics.visit_provenance(visit);
extern_statics_imports.visit_provenance(visit);
}
}

Expand Down Expand Up @@ -1391,7 +1389,13 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {
let extern_decl_layout =
ecx.tcx.layout_of(ecx.typing_env().as_query_input(def_ty)).unwrap();

if let Some(&ptr) = ecx.machine.extern_statics.get(&link_name) {
// Look up the `ptr` in the right map, depending on whether this is an "import"
// static or a real one.
let ptr = match ecx.tcx.codegen_fn_attrs(def_id).import_linkage {
None => ecx.machine.extern_statics.get(&link_name),
Some(_) => ecx.machine.extern_statics_imports.get(&link_name),
};
if let Some(&ptr) = ptr {
// Various parts of the engine rely on `get_alloc_info` for size and alignment
// information. That uses the type information of this static.
// Make sure it matches the Miri allocation for this.
Expand Down Expand Up @@ -1429,7 +1433,7 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {
);
interp_ok(
ecx.machine
.missing_weak_symbol
.extern_static_weak_import_default
.expect("`missing_weak_symbol` should have been initialized"),
)
} else {
Expand Down
14 changes: 12 additions & 2 deletions src/provenance_gc.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use std::collections::BTreeMap;

use rustc_data_structures::either::Either;
use rustc_data_structures::fx::FxHashSet;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_span::Symbol;

use crate::*;

Expand All @@ -21,7 +22,7 @@ macro_rules! no_provenance {
)+
}
}
no_provenance!(i8 i16 i32 i64 isize u8 u16 u32 u64 usize bool ThreadId Deadline);
no_provenance!(i8 i16 i32 i64 isize u8 u16 u32 u64 usize bool ThreadId Deadline Symbol);

impl VisitProvenance for &'static str {
fn visit_provenance(&self, _visit: &mut VisitWith<'_>) {}
Expand Down Expand Up @@ -61,6 +62,15 @@ impl<K: VisitProvenance, V: VisitProvenance> VisitProvenance for BTreeMap<K, V>
}
}

impl<K: VisitProvenance, V: VisitProvenance> VisitProvenance for FxHashMap<K, V> {
fn visit_provenance(&self, visit: &mut VisitWith<'_>) {
self.iter().for_each(|(key, value)| {
key.visit_provenance(visit);
value.visit_provenance(visit);
});
}
}

impl<T: VisitProvenance> VisitProvenance for std::cell::RefCell<T> {
fn visit_provenance(&self, visit: &mut VisitWith<'_>) {
self.borrow().visit_provenance(visit)
Expand Down
43 changes: 30 additions & 13 deletions src/shims/extern_static.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
//! Provides the `extern static` that this platform expects.

use rustc_span::Symbol;
use rustc_target::spec::Os;

use crate::*;

impl<'tcx> MiriMachine<'tcx> {
fn add_extern_static(ecx: &mut MiriInterpCx<'tcx>, name: &str, ptr: Pointer) {
// This got just allocated, so there definitely is a pointer here.
let ptr = ptr.into_pointer_or_addr().unwrap();
ecx.machine.extern_statics.try_insert(Symbol::intern(name), ptr).unwrap();
}

fn alloc_extern_static(
ecx: &mut MiriInterpCx<'tcx>,
name: &str,
Expand All @@ -16,17 +23,27 @@ impl<'tcx> MiriMachine<'tcx> {
interp_ok(())
}

/// Extern statics that are initialized with function pointers to the symbols of the same name.
fn weak_symbol_extern_statics(
/// Make `ptr` available as a weak symbol with the given name.
fn add_weak_symbol(
ecx: &mut MiriInterpCx<'tcx>,
names: &[&str],
name: &str,
ptr: Pointer,
) -> InterpResult<'tcx> {
// Allocate the extra indirection place and add it to the map.
let layout = ecx.machine.layouts.mut_raw_ptr;
let place = ecx.allocate(layout, MiriMemoryKind::ExternStatic.into())?;
ecx.write_scalar(Scalar::from_maybe_pointer(ptr, ecx), &place)?;
let weak_ptr = place.ptr().into_pointer_or_addr().unwrap();
ecx.machine.extern_statics_imports.try_insert(Symbol::intern(name), weak_ptr).unwrap();
interp_ok(())
}

/// Extern statics that are initialized with function pointers to the symbols of the same name.
fn weak_fn_symbols(ecx: &mut MiriInterpCx<'tcx>, names: &[&str]) -> InterpResult<'tcx> {
for name in names {
assert!(ecx.is_dyn_sym(name), "{name} is not a dynamic symbol");
let layout = ecx.machine.layouts.const_raw_ptr;
let ptr = ecx.fn_ptr(FnVal::Other(DynSym::from_str(name)));
let val = ImmTy::from_scalar(Scalar::from_pointer(ptr, ecx), layout);
Self::alloc_extern_static(ecx, name, val)?;
Self::add_weak_symbol(ecx, name, ptr.into())?;
}
interp_ok(())
}
Expand All @@ -37,17 +54,16 @@ impl<'tcx> MiriMachine<'tcx> {
// "environ" is mandated by POSIX.
let environ = ecx.machine.env_vars.unix().environ();
Self::add_extern_static(ecx, "environ", environ);
// We also provide it as a weak symbol, which is needed on FreeBSD.
Self::add_weak_symbol(ecx, "environ", environ)?;
}

match &ecx.tcx.sess.target.os {
Os::Linux => {
Self::weak_symbol_extern_statics(ecx, &["getrandom", "gettid", "statx", "strlen"])?;
Self::weak_fn_symbols(ecx, &["getrandom", "gettid", "statx", "strlen"])?;
}
Os::Android => {
Self::weak_symbol_extern_statics(
ecx,
&["signal", "getrandom", "gettid", "futimens"],
)?;
Self::weak_fn_symbols(ecx, &["signal", "getrandom", "gettid", "futimens"])?;
}
Os::Windows => {
// "_tls_used"
Expand All @@ -56,15 +72,16 @@ impl<'tcx> MiriMachine<'tcx> {
Self::alloc_extern_static(ecx, "_tls_used", val)?;
}
Os::Illumos | Os::Solaris => {
Self::weak_symbol_extern_statics(ecx, &["pthread_setname_np"])?;
Self::weak_fn_symbols(ecx, &["pthread_setname_np"])?;
}
_ => {} // No "extern statics" supported on this target.
}

// Also initialize `missing_weak_symbol`.
let place = ecx.allocate(ecx.machine.layouts.usize, MiriMemoryKind::ExternStatic.into())?;
ecx.write_null(&place)?;
ecx.machine.missing_weak_symbol = Some(place.ptr().into_pointer_or_addr().unwrap());
ecx.machine.extern_static_weak_import_default =
Some(place.ptr().into_pointer_or_addr().unwrap());

interp_ok(())
}
Expand Down
3 changes: 0 additions & 3 deletions tests/pass/shims/env/var.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
//@compile-flags: -Zmiri-deterministic-concurrency
use std::{env, thread};

fn main() {
Expand Down Expand Up @@ -26,8 +25,6 @@ fn main() {
println!("{:#?}", env::vars().collect::<Vec<_>>());

// Do things concurrently, to make sure there's no data race.
// We disable preemption to make sure the lock is not contended;
// that means we don't hit e.g. the futex codepath on Android (which we don't support).
let t = thread::spawn(|| {
env::set_var("MIRI_TEST", "42");
});
Expand Down
Loading