Merge pull request #4475 from RalfJung/native-lib-optional
make native-lib support compile-time-optional, and centralize cfg usage
This commit is contained in:
commit
aef3d9e845
11 changed files with 54 additions and 37 deletions
|
|
@ -38,14 +38,14 @@ features = ['unprefixed_malloc_on_supported_platforms']
|
|||
|
||||
[target.'cfg(unix)'.dependencies]
|
||||
libc = "0.2"
|
||||
libffi = "4.0.0"
|
||||
libloading = "0.8"
|
||||
libffi = { version = "4.0.0", optional = true }
|
||||
libloading = { version = "0.8", optional = true }
|
||||
nix = { version = "0.30.1", features = ["mman", "ptrace", "signal"], optional = true }
|
||||
|
||||
[target.'cfg(target_os = "linux")'.dependencies]
|
||||
nix = { version = "0.30.1", features = ["mman", "ptrace", "signal"] }
|
||||
ipc-channel = "0.19.0"
|
||||
serde = { version = "1.0.219", features = ["derive"] }
|
||||
capstone = "0.13"
|
||||
ipc-channel = { version = "0.19.0", optional = true }
|
||||
serde = { version = "1.0.219", features = ["derive"], optional = true }
|
||||
capstone = { version = "0.13", optional = true }
|
||||
|
||||
[dev-dependencies]
|
||||
ui_test = "0.29.1"
|
||||
|
|
@ -64,11 +64,12 @@ name = "ui"
|
|||
harness = false
|
||||
|
||||
[features]
|
||||
default = ["stack-cache"]
|
||||
default = ["stack-cache", "native-lib"]
|
||||
genmc = []
|
||||
stack-cache = []
|
||||
stack-cache-consistency-check = ["stack-cache"]
|
||||
tracing = ["serde_json"]
|
||||
native-lib = ["dep:libffi", "dep:libloading", "dep:capstone", "dep:ipc-channel", "dep:nix", "dep:serde"]
|
||||
|
||||
[lints.rust.unexpected_cfgs]
|
||||
level = "warn"
|
||||
|
|
|
|||
|
|
@ -26,5 +26,6 @@ invocationStrategy = "once"
|
|||
overrideCommand = [
|
||||
"./miri",
|
||||
"check",
|
||||
"--no-default-features",
|
||||
"--message-format=json",
|
||||
]
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
"rust-analyzer.cargo.buildScripts.overrideCommand": [
|
||||
"./miri",
|
||||
"check",
|
||||
"--no-default-features",
|
||||
"--message-format=json",
|
||||
],
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,20 +1,18 @@
|
|||
use std::alloc::Layout;
|
||||
use std::borrow::Cow;
|
||||
use std::cell::RefCell;
|
||||
use std::rc::Rc;
|
||||
use std::{alloc, slice};
|
||||
#[cfg(target_os = "linux")]
|
||||
use std::{cell::RefCell, rc::Rc};
|
||||
|
||||
use rustc_abi::{Align, Size};
|
||||
use rustc_middle::mir::interpret::AllocBytes;
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
use crate::alloc::isolated_alloc::IsolatedAlloc;
|
||||
use crate::helpers::ToU64 as _;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum MiriAllocParams {
|
||||
Global,
|
||||
#[cfg(target_os = "linux")]
|
||||
Isolated(Rc<RefCell<IsolatedAlloc>>),
|
||||
}
|
||||
|
||||
|
|
@ -56,7 +54,6 @@ impl Drop for MiriAllocBytes {
|
|||
unsafe {
|
||||
match self.params.clone() {
|
||||
MiriAllocParams::Global => alloc::dealloc(self.ptr, alloc_layout),
|
||||
#[cfg(target_os = "linux")]
|
||||
MiriAllocParams::Isolated(alloc) =>
|
||||
alloc.borrow_mut().dealloc(self.ptr, alloc_layout),
|
||||
}
|
||||
|
|
@ -123,7 +120,6 @@ impl AllocBytes for MiriAllocBytes {
|
|||
let alloc_fn = |layout, params: &MiriAllocParams| unsafe {
|
||||
match params {
|
||||
MiriAllocParams::Global => alloc::alloc(layout),
|
||||
#[cfg(target_os = "linux")]
|
||||
MiriAllocParams::Isolated(alloc) => alloc.borrow_mut().alloc(layout),
|
||||
}
|
||||
};
|
||||
|
|
@ -144,7 +140,6 @@ impl AllocBytes for MiriAllocBytes {
|
|||
let alloc_fn = |layout, params: &MiriAllocParams| unsafe {
|
||||
match params {
|
||||
MiriAllocParams::Global => alloc::alloc_zeroed(layout),
|
||||
#[cfg(target_os = "linux")]
|
||||
MiriAllocParams::Isolated(alloc) => alloc.borrow_mut().alloc_zeroed(layout),
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,5 +1,31 @@
|
|||
mod alloc_bytes;
|
||||
#[cfg(target_os = "linux")]
|
||||
#[cfg(all(unix, feature = "native-lib"))]
|
||||
pub mod isolated_alloc;
|
||||
#[cfg(not(all(unix, feature = "native-lib")))]
|
||||
pub mod isolated_alloc {
|
||||
use std::alloc::Layout;
|
||||
|
||||
/// Stub allocator to avoid `cfg`s in the rest of Miri.
|
||||
#[derive(Debug)]
|
||||
pub struct IsolatedAlloc(!);
|
||||
|
||||
impl IsolatedAlloc {
|
||||
pub fn new() -> Self {
|
||||
unreachable!()
|
||||
}
|
||||
|
||||
pub unsafe fn alloc(&mut self, _layout: Layout) -> *mut u8 {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub unsafe fn alloc_zeroed(&mut self, _layout: Layout) -> *mut u8 {
|
||||
match self.0 {}
|
||||
}
|
||||
|
||||
pub unsafe fn dealloc(&mut self, _ptr: *mut u8, _layout: Layout) {
|
||||
match self.0 {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub use self::alloc_bytes::{MiriAllocBytes, MiriAllocParams};
|
||||
|
|
|
|||
|
|
@ -335,9 +335,10 @@ impl rustc_driver::Callbacks for MiriBeRustCompilerCalls {
|
|||
fn exit(exit_code: i32) -> ! {
|
||||
// Drop the tracing guard before exiting, so tracing calls are flushed correctly.
|
||||
deinit_loggers();
|
||||
// Make sure the supervisor knows about the code code.
|
||||
#[cfg(target_os = "linux")]
|
||||
// Make sure the supervisor knows about the exit code.
|
||||
#[cfg(all(unix, feature = "native-lib"))]
|
||||
miri::native_lib::register_retcode_sv(exit_code);
|
||||
// Actually exit.
|
||||
std::process::exit(exit_code);
|
||||
}
|
||||
|
||||
|
|
@ -754,7 +755,7 @@ fn main() {
|
|||
debug!("crate arguments: {:?}", miri_config.args);
|
||||
if !miri_config.native_lib.is_empty() && miri_config.native_lib_enable_tracing {
|
||||
// SAFETY: No other threads are running
|
||||
#[cfg(target_os = "linux")]
|
||||
#[cfg(all(unix, feature = "native-lib"))]
|
||||
if unsafe { miri::native_lib::init_sv() }.is_err() {
|
||||
eprintln!(
|
||||
"warning: The native-lib tracer could not be started. Is this an x86 Linux system, and does Miri have permissions to ptrace?\n\
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ pub use rustc_const_eval::interpret::{self, AllocMap, Provenance as _};
|
|||
use rustc_middle::{bug, span_bug};
|
||||
use tracing::{info, trace};
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[cfg(all(unix, feature = "native-lib"))]
|
||||
pub mod native_lib {
|
||||
pub use crate::shims::{init_sv, register_retcode_sv};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -530,7 +530,6 @@ pub struct MiriMachine<'tcx> {
|
|||
pub(crate) rng: RefCell<StdRng>,
|
||||
|
||||
/// The allocator used for the machine's `AllocBytes` in native-libs mode.
|
||||
#[cfg(target_os = "linux")]
|
||||
pub(crate) allocator: Option<Rc<RefCell<crate::alloc::isolated_alloc::IsolatedAlloc>>>,
|
||||
|
||||
/// The allocation IDs to report when they are being allocated
|
||||
|
|
@ -554,9 +553,9 @@ pub struct MiriMachine<'tcx> {
|
|||
pub(crate) basic_block_count: u64,
|
||||
|
||||
/// Handle of the optional shared object file for native functions.
|
||||
#[cfg(unix)]
|
||||
#[cfg(all(unix, feature = "native-lib"))]
|
||||
pub native_lib: Vec<(libloading::Library, std::path::PathBuf)>,
|
||||
#[cfg(not(unix))]
|
||||
#[cfg(not(all(unix, feature = "native-lib")))]
|
||||
pub native_lib: Vec<!>,
|
||||
|
||||
/// Run a garbage collector for BorTags every N basic blocks.
|
||||
|
|
@ -603,7 +602,7 @@ pub struct MiriMachine<'tcx> {
|
|||
/// Remembers whether we already warned about an extern type with Stacked Borrows.
|
||||
pub(crate) sb_extern_type_warned: Cell<bool>,
|
||||
/// Remember whether we already warned about sharing memory with a native call.
|
||||
#[cfg(unix)]
|
||||
#[allow(unused)]
|
||||
pub(crate) native_call_mem_warned: Cell<bool>,
|
||||
/// Remembers which shims have already shown the warning about erroring in isolation.
|
||||
pub(crate) reject_in_isolation_warned: RefCell<FxHashSet<String>>,
|
||||
|
|
@ -718,7 +717,6 @@ impl<'tcx> MiriMachine<'tcx> {
|
|||
local_crates,
|
||||
extern_statics: FxHashMap::default(),
|
||||
rng: RefCell::new(rng),
|
||||
#[cfg(target_os = "linux")]
|
||||
allocator: if !config.native_lib.is_empty() {
|
||||
Some(Rc::new(RefCell::new(crate::alloc::isolated_alloc::IsolatedAlloc::new())))
|
||||
} else { None },
|
||||
|
|
@ -730,7 +728,7 @@ impl<'tcx> MiriMachine<'tcx> {
|
|||
report_progress: config.report_progress,
|
||||
basic_block_count: 0,
|
||||
monotonic_clock: MonotonicClock::new(config.isolated_op == IsolatedOp::Allow),
|
||||
#[cfg(unix)]
|
||||
#[cfg(all(unix, feature = "native-lib"))]
|
||||
native_lib: config.native_lib.iter().map(|lib_file_path| {
|
||||
let host_triple = rustc_session::config::host_tuple();
|
||||
let target_triple = tcx.sess.opts.target_triple.tuple();
|
||||
|
|
@ -752,9 +750,9 @@ impl<'tcx> MiriMachine<'tcx> {
|
|||
lib_file_path.clone(),
|
||||
)
|
||||
}).collect(),
|
||||
#[cfg(not(unix))]
|
||||
#[cfg(not(all(unix, feature = "native-lib")))]
|
||||
native_lib: config.native_lib.iter().map(|_| {
|
||||
panic!("calling functions from native libraries via FFI is only supported on Unix")
|
||||
panic!("calling functions from native libraries via FFI is not supported in this build of Miri")
|
||||
}).collect(),
|
||||
gc_interval: config.gc_interval,
|
||||
since_gc: 0,
|
||||
|
|
@ -771,7 +769,6 @@ impl<'tcx> MiriMachine<'tcx> {
|
|||
pthread_rwlock_sanity: Cell::new(false),
|
||||
pthread_condvar_sanity: Cell::new(false),
|
||||
sb_extern_type_warned: Cell::new(false),
|
||||
#[cfg(unix)]
|
||||
native_call_mem_warned: Cell::new(false),
|
||||
reject_in_isolation_warned: Default::default(),
|
||||
int2ptr_warned: Default::default(),
|
||||
|
|
@ -924,7 +921,6 @@ impl VisitProvenance for MiriMachine<'_> {
|
|||
backtrace_style: _,
|
||||
local_crates: _,
|
||||
rng: _,
|
||||
#[cfg(target_os = "linux")]
|
||||
allocator: _,
|
||||
tracked_alloc_ids: _,
|
||||
track_alloc_accesses: _,
|
||||
|
|
@ -949,7 +945,6 @@ impl VisitProvenance for MiriMachine<'_> {
|
|||
pthread_rwlock_sanity: _,
|
||||
pthread_condvar_sanity: _,
|
||||
sb_extern_type_warned: _,
|
||||
#[cfg(unix)]
|
||||
native_call_mem_warned: _,
|
||||
reject_in_isolation_warned: _,
|
||||
int2ptr_warned: _,
|
||||
|
|
@ -1817,13 +1812,10 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {
|
|||
fn get_default_alloc_params(&self) -> <Self::Bytes as AllocBytes>::AllocParams {
|
||||
use crate::alloc::MiriAllocParams;
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
match &self.allocator {
|
||||
Some(alloc) => MiriAllocParams::Isolated(alloc.clone()),
|
||||
None => MiriAllocParams::Global,
|
||||
}
|
||||
#[cfg(not(target_os = "linux"))]
|
||||
MiriAllocParams::Global
|
||||
}
|
||||
|
||||
fn enter_trace_span(span: impl FnOnce() -> tracing::Span) -> impl EnteredTraceSpan {
|
||||
|
|
|
|||
|
|
@ -237,7 +237,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
let this = self.eval_context_mut();
|
||||
|
||||
// First deal with any external C functions in linked .so file.
|
||||
#[cfg(unix)]
|
||||
#[cfg(all(unix, feature = "native-lib"))]
|
||||
if !this.machine.native_lib.is_empty() {
|
||||
use crate::shims::native_lib::EvalContextExt as _;
|
||||
// An Ok(false) here means that the function being called was not exported
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ mod aarch64;
|
|||
mod alloc;
|
||||
mod backtrace;
|
||||
mod files;
|
||||
#[cfg(unix)]
|
||||
#[cfg(all(unix, feature = "native-lib"))]
|
||||
mod native_lib;
|
||||
mod unix;
|
||||
mod wasi;
|
||||
|
|
@ -23,7 +23,7 @@ pub mod tls;
|
|||
pub mod unwind;
|
||||
|
||||
pub use self::files::FdTable;
|
||||
#[cfg(target_os = "linux")]
|
||||
#[cfg(all(unix, feature = "native-lib"))]
|
||||
pub use self::native_lib::trace::{init_sv, register_retcode_sv};
|
||||
pub use self::unix::{DirTable, EpollInterestTable};
|
||||
|
||||
|
|
|
|||
|
|
@ -335,7 +335,7 @@ fn main() -> Result<()> {
|
|||
ui(Mode::Panic, "tests/panic", &target, WithDependencies, tmpdir.path())?;
|
||||
ui(Mode::Fail, "tests/fail", &target, WithoutDependencies, tmpdir.path())?;
|
||||
ui(Mode::Fail, "tests/fail-dep", &target, WithDependencies, tmpdir.path())?;
|
||||
if cfg!(unix) && target == host {
|
||||
if cfg!(all(unix, feature = "native-lib")) && target == host {
|
||||
ui(Mode::Pass, "tests/native-lib/pass", &target, WithoutDependencies, tmpdir.path())?;
|
||||
ui(Mode::Fail, "tests/native-lib/fail", &target, WithoutDependencies, tmpdir.path())?;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue