miri/shims/
extern_static.rs1use rustc_span::Symbol;
4use rustc_target::spec::{Env, Os};
5
6use crate::*;
7
8impl<'tcx> MiriMachine<'tcx> {
9 fn add_extern_static(ecx: &mut MiriInterpCx<'tcx>, name: &str, ptr: Pointer) {
10 let ptr = ptr.into_pointer_or_addr().unwrap();
12 ecx.machine.extern_statics.try_insert(Symbol::intern(name), ptr).unwrap();
13 }
14
15 fn alloc_extern_static(
16 ecx: &mut MiriInterpCx<'tcx>,
17 name: &str,
18 val: ImmTy<'tcx>,
19 ) -> InterpResult<'tcx, Pointer> {
20 let place = ecx.allocate(val.layout, MiriMemoryKind::ExternStatic.into())?;
21 ecx.write_immediate(*val, &place)?;
22 Self::add_extern_static(ecx, name, place.ptr());
23 interp_ok(place.ptr())
24 }
25
26 fn add_weak_symbol(
28 ecx: &mut MiriInterpCx<'tcx>,
29 name: &str,
30 ptr: Pointer,
31 ) -> InterpResult<'tcx> {
32 let layout = ecx.machine.layouts.unit_ptr_mut;
34 let place = ecx.allocate(layout, MiriMemoryKind::ExternStatic.into())?;
35 ecx.write_scalar(Scalar::from_maybe_pointer(ptr, ecx), &place)?;
36 let weak_ptr = place.ptr().into_pointer_or_addr().unwrap();
37 ecx.machine.extern_statics_imports.try_insert(Symbol::intern(name), weak_ptr).unwrap();
38 interp_ok(())
39 }
40
41 fn weak_fn_symbols(ecx: &mut MiriInterpCx<'tcx>, names: &[&str]) -> InterpResult<'tcx> {
43 for name in names {
44 assert!(ecx.is_dyn_sym(name), "{name} is not a dynamic symbol");
45 let ptr = ecx.fn_ptr(FnVal::Other(DynSym::from_str(name)));
46 Self::add_weak_symbol(ecx, name, ptr.into())?;
47 }
48 interp_ok(())
49 }
50
51 pub fn init_extern_statics(ecx: &mut MiriInterpCx<'tcx>) -> InterpResult<'tcx> {
53 if ecx.target_os_is_unix() {
54 let environ = ecx.machine.env_vars.unix().environ();
56 Self::add_extern_static(ecx, "environ", environ);
57 Self::add_weak_symbol(ecx, "environ", environ)?;
59 }
60
61 match &ecx.tcx.sess.target.os {
62 Os::Linux => {
63 Self::weak_fn_symbols(
64 ecx,
65 &["copy_file_range", "getrandom", "gettid", "statx", "strlen"],
66 )?;
67 if ecx.is_dyn_sym("__futimens64") {
68 Self::weak_fn_symbols(ecx, &["__futimens64"])?;
69 }
70 if ecx.tcx.sess.target.env == Env::Gnu {
71 if ecx.machine.data_race.as_genmc_ref().is_none() {
74 Self::weak_fn_symbols(ecx, &["__cxa_thread_atexit_impl"])?;
75 }
76 let val = ImmTy::from_int(0, ecx.machine.layouts.u8);
78 let ptr = Self::alloc_extern_static(ecx, "__dso_handle", val)?;
79 Self::add_weak_symbol(ecx, "__dso_handle", ptr)?;
81 }
82 }
83 Os::Android => {
84 Self::weak_fn_symbols(
85 ecx,
86 &["signal", "getrandom", "gettid", "futimens", "preadv", "pwritev"],
87 )?;
88 }
89 Os::Windows => {
90 let val = ImmTy::from_int(0, ecx.machine.layouts.u8);
93 Self::alloc_extern_static(ecx, "_tls_used", val)?;
94 }
95 Os::Illumos | Os::Solaris => {
96 Self::weak_fn_symbols(ecx, &["pthread_setname_np"])?;
97 }
98 _ => {} }
100
101 let place = ecx.allocate(ecx.machine.layouts.usize, MiriMemoryKind::ExternStatic.into())?;
103 ecx.write_int(0, &place)?;
104 ecx.machine.extern_static_weak_import_default =
105 Some(place.ptr().into_pointer_or_addr().unwrap());
106
107 interp_ok(())
108 }
109}