Skip to content

Commit 4e8ad10

Browse files
committed
Auto merge of #3277 - RalfJung:freebsd, r=RalfJung
add __cxa_thread_atexit_impl on freebsd Fixes rust-lang/miri#3276
2 parents cf22ee0 + 12dd3bf commit 4e8ad10

File tree

5 files changed

+98
-116
lines changed

5 files changed

+98
-116
lines changed

src/tools/miri/ci/ci.sh

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -121,9 +121,8 @@ case $HOST_TARGET in
121121
MIRI_TEST_TARGET=aarch64-apple-darwin run_tests
122122
MIRI_TEST_TARGET=i686-pc-windows-gnu run_tests
123123
# Some targets are only partially supported.
124-
# FIXME: freeBSD disabled due to https://github.com/rust-lang/miri/issues/3276
125-
#MIRI_TEST_TARGET=x86_64-unknown-freebsd run_tests_minimal hello integer vec panic/panic concurrency/simple pthread-threadname libc-getentropy libc-getrandom libc-misc libc-fs atomic env align
126-
#MIRI_TEST_TARGET=i686-unknown-freebsd run_tests_minimal hello integer vec panic/panic concurrency/simple pthread-threadname libc-getentropy libc-getrandom libc-misc libc-fs atomic env align
124+
MIRI_TEST_TARGET=x86_64-unknown-freebsd run_tests_minimal hello integer vec panic/panic concurrency/simple pthread-threadname libc-getentropy libc-getrandom libc-misc libc-fs atomic env align
125+
MIRI_TEST_TARGET=i686-unknown-freebsd run_tests_minimal hello integer vec panic/panic concurrency/simple pthread-threadname libc-getentropy libc-getrandom libc-misc libc-fs atomic env align
127126
MIRI_TEST_TARGET=aarch64-linux-android run_tests_minimal hello integer vec panic/panic
128127
MIRI_TEST_TARGET=wasm32-wasi run_tests_minimal no_std integer strings wasm
129128
MIRI_TEST_TARGET=wasm32-unknown-unknown run_tests_minimal no_std integer strings wasm

src/tools/miri/src/lib.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,6 @@ pub use crate::shims::os_str::EvalContextExt as _;
9494
pub use crate::shims::panic::{CatchUnwindData, EvalContextExt as _};
9595
pub use crate::shims::time::EvalContextExt as _;
9696
pub use crate::shims::tls::TlsData;
97-
pub use crate::shims::EvalContextExt as _;
9897

9998
pub use crate::borrow_tracker::stacked_borrows::{
10099
EvalContextExt as _, Item, Permission, Stack, Stacks,

src/tools/miri/src/machine.rs

Lines changed: 16 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -691,7 +691,7 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> {
691691
Ok(())
692692
}
693693

694-
fn add_extern_static(
694+
pub(crate) fn add_extern_static(
695695
this: &mut MiriInterpCx<'mir, 'tcx>,
696696
name: &str,
697697
ptr: Pointer<Option<Provenance>>,
@@ -701,75 +701,6 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> {
701701
this.machine.extern_statics.try_insert(Symbol::intern(name), ptr).unwrap();
702702
}
703703

704-
fn alloc_extern_static(
705-
this: &mut MiriInterpCx<'mir, 'tcx>,
706-
name: &str,
707-
val: ImmTy<'tcx, Provenance>,
708-
) -> InterpResult<'tcx> {
709-
let place = this.allocate(val.layout, MiriMemoryKind::ExternStatic.into())?;
710-
this.write_immediate(*val, &place)?;
711-
Self::add_extern_static(this, name, place.ptr());
712-
Ok(())
713-
}
714-
715-
/// Sets up the "extern statics" for this machine.
716-
fn init_extern_statics(this: &mut MiriInterpCx<'mir, 'tcx>) -> InterpResult<'tcx> {
717-
// "__rust_no_alloc_shim_is_unstable"
718-
let val = ImmTy::from_int(0, this.machine.layouts.u8);
719-
Self::alloc_extern_static(this, "__rust_no_alloc_shim_is_unstable", val)?;
720-
721-
match this.tcx.sess.target.os.as_ref() {
722-
"linux" => {
723-
// "environ"
724-
Self::add_extern_static(
725-
this,
726-
"environ",
727-
this.machine.env_vars.environ.as_ref().unwrap().ptr(),
728-
);
729-
// A couple zero-initialized pointer-sized extern statics.
730-
// Most of them are for weak symbols, which we all set to null (indicating that the
731-
// symbol is not supported, and triggering fallback code which ends up calling a
732-
// syscall that we do support).
733-
for name in &["__cxa_thread_atexit_impl", "getrandom", "statx", "__clock_gettime64"]
734-
{
735-
let val = ImmTy::from_int(0, this.machine.layouts.usize);
736-
Self::alloc_extern_static(this, name, val)?;
737-
}
738-
}
739-
"freebsd" => {
740-
// "environ"
741-
Self::add_extern_static(
742-
this,
743-
"environ",
744-
this.machine.env_vars.environ.as_ref().unwrap().ptr(),
745-
);
746-
}
747-
"android" => {
748-
// "signal" -- just needs a non-zero pointer value (function does not even get called),
749-
// but we arrange for this to be callable anyway (it will then do nothing).
750-
let layout = this.machine.layouts.const_raw_ptr;
751-
let ptr = this.fn_ptr(FnVal::Other(DynSym::from_str("signal")));
752-
let val = ImmTy::from_scalar(Scalar::from_pointer(ptr, this), layout);
753-
Self::alloc_extern_static(this, "signal", val)?;
754-
// A couple zero-initialized pointer-sized extern statics.
755-
// Most of them are for weak symbols, which we all set to null (indicating that the
756-
// symbol is not supported, and triggering fallback code.)
757-
for name in &["bsd_signal"] {
758-
let val = ImmTy::from_int(0, this.machine.layouts.usize);
759-
Self::alloc_extern_static(this, name, val)?;
760-
}
761-
}
762-
"windows" => {
763-
// "_tls_used"
764-
// This is some obscure hack that is part of the Windows TLS story. It's a `u8`.
765-
let val = ImmTy::from_int(0, this.machine.layouts.u8);
766-
Self::alloc_extern_static(this, "_tls_used", val)?;
767-
}
768-
_ => {} // No "extern statics" supported on this target
769-
}
770-
Ok(())
771-
}
772-
773704
pub(crate) fn communicate(&self) -> bool {
774705
self.isolated_op == IsolatedOp::Allow
775706
}
@@ -989,7 +920,21 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
989920
ret: Option<mir::BasicBlock>,
990921
unwind: mir::UnwindAction,
991922
) -> InterpResult<'tcx, Option<(&'mir mir::Body<'tcx>, ty::Instance<'tcx>)>> {
992-
ecx.find_mir_or_eval_fn(instance, abi, args, dest, ret, unwind)
923+
// For foreign items, try to see if we can emulate them.
924+
if ecx.tcx.is_foreign_item(instance.def_id()) {
925+
// An external function call that does not have a MIR body. We either find MIR elsewhere
926+
// or emulate its effect.
927+
// This will be Ok(None) if we're emulating the intrinsic entirely within Miri (no need
928+
// to run extra MIR), and Ok(Some(body)) if we found MIR to run for the
929+
// foreign function
930+
// Any needed call to `goto_block` will be performed by `emulate_foreign_item`.
931+
let args = ecx.copy_fn_args(args)?; // FIXME: Should `InPlace` arguments be reset to uninit?
932+
let link_name = ecx.item_link_name(instance.def_id());
933+
return ecx.emulate_foreign_item(link_name, abi, &args, dest, ret, unwind);
934+
}
935+
936+
// Otherwise, load the MIR.
937+
Ok(Some((ecx.load_mir(instance.def, None)?, instance)))
993938
}
994939

995940
#[inline(always)]
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
//! Provides the `extern static` that this platform expects.
2+
3+
use crate::*;
4+
5+
impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> {
6+
fn alloc_extern_static(
7+
this: &mut MiriInterpCx<'mir, 'tcx>,
8+
name: &str,
9+
val: ImmTy<'tcx, Provenance>,
10+
) -> InterpResult<'tcx> {
11+
let place = this.allocate(val.layout, MiriMemoryKind::ExternStatic.into())?;
12+
this.write_immediate(*val, &place)?;
13+
Self::add_extern_static(this, name, place.ptr());
14+
Ok(())
15+
}
16+
17+
/// Zero-initialized pointer-sized extern statics are pretty common.
18+
/// Most of them are for weak symbols, which we all set to null (indicating that the
19+
/// symbol is not supported, and triggering fallback code which ends up calling a
20+
/// syscall that we do support).
21+
fn null_ptr_extern_statics(
22+
this: &mut MiriInterpCx<'mir, 'tcx>,
23+
names: &[&str],
24+
) -> InterpResult<'tcx> {
25+
for name in names {
26+
let val = ImmTy::from_int(0, this.machine.layouts.usize);
27+
Self::alloc_extern_static(this, name, val)?;
28+
}
29+
Ok(())
30+
}
31+
32+
/// Sets up the "extern statics" for this machine.
33+
pub fn init_extern_statics(this: &mut MiriInterpCx<'mir, 'tcx>) -> InterpResult<'tcx> {
34+
// "__rust_no_alloc_shim_is_unstable"
35+
let val = ImmTy::from_int(0, this.machine.layouts.u8);
36+
Self::alloc_extern_static(this, "__rust_no_alloc_shim_is_unstable", val)?;
37+
38+
match this.tcx.sess.target.os.as_ref() {
39+
"linux" => {
40+
Self::null_ptr_extern_statics(
41+
this,
42+
&["__cxa_thread_atexit_impl", "getrandom", "statx", "__clock_gettime64"],
43+
)?;
44+
// "environ"
45+
Self::add_extern_static(
46+
this,
47+
"environ",
48+
this.machine.env_vars.environ.as_ref().unwrap().ptr(),
49+
);
50+
}
51+
"freebsd" => {
52+
Self::null_ptr_extern_statics(this, &["__cxa_thread_atexit_impl"])?;
53+
// "environ"
54+
Self::add_extern_static(
55+
this,
56+
"environ",
57+
this.machine.env_vars.environ.as_ref().unwrap().ptr(),
58+
);
59+
}
60+
"android" => {
61+
Self::null_ptr_extern_statics(this, &["bsd_signal"])?;
62+
// "signal" -- just needs a non-zero pointer value (function does not even get called),
63+
// but we arrange for this to call the `signal` function anyway.
64+
let layout = this.machine.layouts.const_raw_ptr;
65+
let ptr = this.fn_ptr(FnVal::Other(DynSym::from_str("signal")));
66+
let val = ImmTy::from_scalar(Scalar::from_pointer(ptr, this), layout);
67+
Self::alloc_extern_static(this, "signal", val)?;
68+
}
69+
"windows" => {
70+
// "_tls_used"
71+
// This is some obscure hack that is part of the Windows TLS story. It's a `u8`.
72+
let val = ImmTy::from_int(0, this.machine.layouts.u8);
73+
Self::alloc_extern_static(this, "_tls_used", val)?;
74+
}
75+
_ => {} // No "extern statics" supported on this target
76+
}
77+
Ok(())
78+
}
79+
}

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

Lines changed: 1 addition & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -10,48 +10,8 @@ pub mod windows;
1010
mod x86;
1111

1212
pub mod env;
13+
pub mod extern_static;
1314
pub mod os_str;
1415
pub mod panic;
1516
pub mod time;
1617
pub mod tls;
17-
18-
// End module management, begin local code
19-
20-
use log::trace;
21-
22-
use rustc_middle::{mir, ty};
23-
use rustc_target::spec::abi::Abi;
24-
25-
use crate::*;
26-
27-
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {}
28-
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
29-
fn find_mir_or_eval_fn(
30-
&mut self,
31-
instance: ty::Instance<'tcx>,
32-
abi: Abi,
33-
args: &[FnArg<'tcx, Provenance>],
34-
dest: &PlaceTy<'tcx, Provenance>,
35-
ret: Option<mir::BasicBlock>,
36-
unwind: mir::UnwindAction,
37-
) -> InterpResult<'tcx, Option<(&'mir mir::Body<'tcx>, ty::Instance<'tcx>)>> {
38-
let this = self.eval_context_mut();
39-
trace!("eval_fn_call: {:#?}, {:?}", instance, dest);
40-
41-
// For foreign items, try to see if we can emulate them.
42-
if this.tcx.is_foreign_item(instance.def_id()) {
43-
// An external function call that does not have a MIR body. We either find MIR elsewhere
44-
// or emulate its effect.
45-
// This will be Ok(None) if we're emulating the intrinsic entirely within Miri (no need
46-
// to run extra MIR), and Ok(Some(body)) if we found MIR to run for the
47-
// foreign function
48-
// Any needed call to `goto_block` will be performed by `emulate_foreign_item`.
49-
let args = this.copy_fn_args(args)?; // FIXME: Should `InPlace` arguments be reset to uninit?
50-
let link_name = this.item_link_name(instance.def_id());
51-
return this.emulate_foreign_item(link_name, abi, &args, dest, ret, unwind);
52-
}
53-
54-
// Otherwise, load the MIR.
55-
Ok(Some((this.load_mir(instance.def, None)?, instance)))
56-
}
57-
}

0 commit comments

Comments
 (0)