refactor extern static handling
This commit is contained in:
parent
cf22ee0c0c
commit
cba1fdbff3
@ -121,9 +121,8 @@ case $HOST_TARGET in
|
||||
MIRI_TEST_TARGET=aarch64-apple-darwin run_tests
|
||||
MIRI_TEST_TARGET=i686-pc-windows-gnu run_tests
|
||||
# Some targets are only partially supported.
|
||||
# FIXME: freeBSD disabled due to https://github.com/rust-lang/miri/issues/3276
|
||||
#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
|
||||
#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
|
||||
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
|
||||
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
|
||||
MIRI_TEST_TARGET=aarch64-linux-android run_tests_minimal hello integer vec panic/panic
|
||||
MIRI_TEST_TARGET=wasm32-wasi run_tests_minimal no_std integer strings wasm
|
||||
MIRI_TEST_TARGET=wasm32-unknown-unknown run_tests_minimal no_std integer strings wasm
|
||||
|
@ -691,7 +691,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>>,
|
||||
@ -701,75 +701,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
|
||||
}
|
||||
|
78
src/tools/miri/src/shims/extern_static.rs
Normal file
78
src/tools/miri/src/shims/extern_static.rs
Normal file
@ -0,0 +1,78 @@
|
||||
//! 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" => {
|
||||
// "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(())
|
||||
}
|
||||
}
|
@ -10,6 +10,7 @@ pub mod windows;
|
||||
mod x86;
|
||||
|
||||
pub mod env;
|
||||
pub mod extern_static;
|
||||
pub mod os_str;
|
||||
pub mod panic;
|
||||
pub mod time;
|
||||
|
Loading…
x
Reference in New Issue
Block a user