From 1fe852998f698b6175b07fc5e4b134b6b067a512 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Fri, 1 Dec 2023 23:41:07 +0000 Subject: [PATCH] [WIP] solaris/illumos support. --- README.md | 1 + ci/ci.sh | 1 + src/shims/unix/foreign_items.rs | 8 +++- src/shims/unix/mod.rs | 1 + src/shims/unix/solarish/foreign_items.rs | 47 ++++++++++++++++++++++++ src/shims/unix/solarish/mod.rs | 1 + src/shims/unix/sync.rs | 20 +++++----- tests/pass-dep/shims/libc-misc.rs | 2 + 8 files changed, 69 insertions(+), 12 deletions(-) create mode 100644 src/shims/unix/solarish/foreign_items.rs create mode 100644 src/shims/unix/solarish/mod.rs diff --git a/README.md b/README.md index f92cc088e0..5898bffd92 100644 --- a/README.md +++ b/README.md @@ -227,6 +227,7 @@ degree documented below): - We have unofficial support (not maintained by the Miri team itself) for some further operating systems. - `freebsd`: **maintainer wanted**. Supports `std::env` and parts of `std::{thread, fs}`, but not `std::sync`. - `android`: **maintainer wanted**. Support very incomplete, but a basic "hello world" works. + - `solaris/illumos`: @devnexen. Support very incomplete, but a basic "hello world" works. - `wasm`: **maintainer wanted**. Support very incomplete, not even standard output works, but an empty `main` function works. - For targets on other operating systems, Miri might fail before even reaching the `main` function. diff --git a/ci/ci.sh b/ci/ci.sh index d3dee0de61..0cc326ca87 100755 --- a/ci/ci.sh +++ b/ci/ci.sh @@ -146,6 +146,7 @@ case $HOST_TARGET in MIRI_TEST_TARGET=x86_64-unknown-freebsd run_tests_minimal $BASIC panic/panic concurrency/simple atomic threadname libc-getentropy libc-getrandom libc-misc fs env num_cpus MIRI_TEST_TARGET=i686-unknown-freebsd run_tests_minimal $BASIC panic/panic concurrency/simple atomic threadname libc-getentropy libc-getrandom libc-misc fs env num_cpus MIRI_TEST_TARGET=aarch64-linux-android run_tests_minimal $VERY_BASIC hello panic/panic + MIRI_TEST_TARGET=x86_64-unknown-illumos run_tests_minimal $VERY_BASIC hello panic/panic MIRI_TEST_TARGET=wasm32-wasi run_tests_minimal $VERY_BASIC wasm MIRI_TEST_TARGET=wasm32-unknown-unknown run_tests_minimal $VERY_BASIC wasm MIRI_TEST_TARGET=thumbv7em-none-eabihf run_tests_minimal no_std diff --git a/src/shims/unix/foreign_items.rs b/src/shims/unix/foreign_items.rs index bd299aaa12..35dd77afe0 100644 --- a/src/shims/unix/foreign_items.rs +++ b/src/shims/unix/foreign_items.rs @@ -14,6 +14,7 @@ use shims::foreign_items::EmulateForeignItemResult; use shims::unix::freebsd::foreign_items as freebsd; use shims::unix::linux::foreign_items as linux; use shims::unix::macos::foreign_items as macos; +use shims::unix::solarish::foreign_items as solarish; fn is_dyn_sym(name: &str, target_os: &str) -> bool { match name { @@ -30,6 +31,7 @@ fn is_dyn_sym(name: &str, target_os: &str) -> bool { "freebsd" => freebsd::is_dyn_sym(name), "linux" => linux::is_dyn_sym(name), "macos" => macos::is_dyn_sym(name), + "solaris" | "illumos" => solarish::is_dyn_sym(name), _ => false, }, } @@ -592,8 +594,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { } "getentropy" => { // This function is non-standard but exists with the same signature and behavior on - // Linux, macOS, and FreeBSD. - if !matches!(&*this.tcx.sess.target.os, "linux" | "macos" | "freebsd") { + // Linux, macOS, FreeBSD and Solaris/Illumos. + if !matches!(&*this.tcx.sess.target.os, "linux" | "macos" | "freebsd" | "illumos" | "solaris") { throw_unsup_format!( "`getentropy` is not supported on {}", this.tcx.sess.target.os @@ -609,6 +611,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { // FreeBSD: https://man.freebsd.org/cgi/man.cgi?query=getentropy&sektion=3&format=html // Linux: https://man7.org/linux/man-pages/man3/getentropy.3.html // macOS: https://keith.github.io/xcode-man-pages/getentropy.2.html + // Solaris/Illumos: https://illumos.org/man/3C/getentropy if bufsize > 256 { let err = this.eval_libc("EIO"); this.set_last_error(err)?; @@ -750,6 +753,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { "freebsd" => freebsd::EvalContextExt::emulate_foreign_item_inner(this, link_name, abi, args, dest), "linux" => linux::EvalContextExt::emulate_foreign_item_inner(this, link_name, abi, args, dest), "macos" => macos::EvalContextExt::emulate_foreign_item_inner(this, link_name, abi, args, dest), + "solaris" | "illumos" => solarish::EvalContextExt::emulate_foreign_item_inner(this, link_name, abi, args, dest), _ => Ok(EmulateForeignItemResult::NotSupported), }; } diff --git a/src/shims/unix/mod.rs b/src/shims/unix/mod.rs index bede2fbd38..6dee30d895 100644 --- a/src/shims/unix/mod.rs +++ b/src/shims/unix/mod.rs @@ -11,6 +11,7 @@ mod thread; mod freebsd; mod linux; mod macos; +mod solarish; pub use env::UnixEnvVars; pub use fd::{FdTable, FileDescription}; diff --git a/src/shims/unix/solarish/foreign_items.rs b/src/shims/unix/solarish/foreign_items.rs new file mode 100644 index 0000000000..f3b3f35df7 --- /dev/null +++ b/src/shims/unix/solarish/foreign_items.rs @@ -0,0 +1,47 @@ +use rustc_span::Symbol; +use rustc_target::spec::abi::Abi; + +use crate::shims::unix::*; +use crate::*; +use shims::foreign_items::EmulateForeignItemResult; + +pub fn is_dyn_sym(_name: &str) -> bool { + false +} + +impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} +pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { + fn emulate_foreign_item_inner( + &mut self, + link_name: Symbol, + abi: Abi, + args: &[OpTy<'tcx, Provenance>], + dest: &MPlaceTy<'tcx, Provenance>, + ) -> InterpResult<'tcx, EmulateForeignItemResult> { + let this = self.eval_context_mut(); + match link_name.as_str() { + // errno + "__errno" => { + let [] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let errno_place = this.last_error_place()?; + this.write_scalar(errno_place.to_ref(this).to_scalar(), dest)?; + } + // Threading + "pthread_condattr_setclock" => { + let [attr, clock_id] = + this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let result = this.pthread_condattr_setclock(attr, clock_id)?; + this.write_scalar(result, dest)?; + } + "pthread_condattr_getclock" => { + let [attr, clock_id] = + this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let result = this.pthread_condattr_getclock(attr, clock_id)?; + this.write_scalar(result, dest)?; + } + + _ => return Ok(EmulateForeignItemResult::NotSupported), + } + Ok(EmulateForeignItemResult::NeedsJumping) + } +} diff --git a/src/shims/unix/solarish/mod.rs b/src/shims/unix/solarish/mod.rs new file mode 100644 index 0000000000..09c6507b24 --- /dev/null +++ b/src/shims/unix/solarish/mod.rs @@ -0,0 +1 @@ +pub mod foreign_items; diff --git a/src/shims/unix/sync.rs b/src/shims/unix/sync.rs index e50a8934e0..9f3aade0cb 100644 --- a/src/shims/unix/sync.rs +++ b/src/shims/unix/sync.rs @@ -279,7 +279,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { ) -> InterpResult<'tcx, i32> { let this = self.eval_context_mut(); - if !matches!(&*this.tcx.sess.target.os, "linux" | "macos") { + if !matches!(&*this.tcx.sess.target.os, "linux" | "macos" | "solaris" | "illumos") { throw_unsup_format!( "`pthread_mutexattr_init` is not supported on {}", this.tcx.sess.target.os @@ -368,7 +368,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { ) -> InterpResult<'tcx, i32> { let this = self.eval_context_mut(); - if !matches!(&*this.tcx.sess.target.os, "linux" | "macos") { + if !matches!(&*this.tcx.sess.target.os, "linux" | "macos" | "solaris" | "illumos") { throw_unsup_format!( "`pthread_mutex_init` is not supported on {}", this.tcx.sess.target.os @@ -529,7 +529,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { ) -> InterpResult<'tcx, i32> { let this = self.eval_context_mut(); - if !matches!(&*this.tcx.sess.target.os, "linux" | "macos") { + if !matches!(&*this.tcx.sess.target.os, "linux" | "macos" | "solaris" | "illumos") { throw_unsup_format!( "`pthread_rwlock_rdlock` is not supported on {}", this.tcx.sess.target.os @@ -554,7 +554,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { ) -> InterpResult<'tcx, i32> { let this = self.eval_context_mut(); - if !matches!(&*this.tcx.sess.target.os, "linux" | "macos") { + if !matches!(&*this.tcx.sess.target.os, "linux" | "macos" | "solaris" | "illumos") { throw_unsup_format!( "`pthread_rwlock_tryrdlock` is not supported on {}", this.tcx.sess.target.os @@ -578,7 +578,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { ) -> InterpResult<'tcx, i32> { let this = self.eval_context_mut(); - if !matches!(&*this.tcx.sess.target.os, "linux" | "macos") { + if !matches!(&*this.tcx.sess.target.os, "linux" | "macos" | "solaris" | "illumos") { throw_unsup_format!( "`pthread_rwlock_wrlock` is not supported on {}", this.tcx.sess.target.os @@ -615,7 +615,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { ) -> InterpResult<'tcx, i32> { let this = self.eval_context_mut(); - if !matches!(&*this.tcx.sess.target.os, "linux" | "macos") { + if !matches!(&*this.tcx.sess.target.os, "linux" | "macos" | "solaris" | "illumos") { throw_unsup_format!( "`pthread_rwlock_trywrlock` is not supported on {}", this.tcx.sess.target.os @@ -639,7 +639,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { ) -> InterpResult<'tcx, i32> { let this = self.eval_context_mut(); - if !matches!(&*this.tcx.sess.target.os, "linux" | "macos") { + if !matches!(&*this.tcx.sess.target.os, "linux" | "macos" | "solaris" | "illumos") { throw_unsup_format!( "`pthread_rwlock_unlock` is not supported on {}", this.tcx.sess.target.os @@ -665,7 +665,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { ) -> InterpResult<'tcx, i32> { let this = self.eval_context_mut(); - if !matches!(&*this.tcx.sess.target.os, "linux" | "macos") { + if !matches!(&*this.tcx.sess.target.os, "linux" | "macos" | "solaris" | "illumos") { throw_unsup_format!( "`pthread_rwlock_destroy` is not supported on {}", this.tcx.sess.target.os @@ -696,7 +696,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { ) -> InterpResult<'tcx, i32> { let this = self.eval_context_mut(); - if !matches!(&*this.tcx.sess.target.os, "linux" | "macos") { + if !matches!(&*this.tcx.sess.target.os, "linux" | "macos" | "solaris" | "illumos") { throw_unsup_format!( "`pthread_condattr_init` is not supported on {}", this.tcx.sess.target.os @@ -769,7 +769,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { ) -> InterpResult<'tcx, i32> { let this = self.eval_context_mut(); - if !matches!(&*this.tcx.sess.target.os, "linux" | "macos") { + if !matches!(&*this.tcx.sess.target.os, "linux" | "macos" | "solaris" | "illumos") { throw_unsup_format!( "`pthread_cond_init` is not supported on {}", this.tcx.sess.target.os diff --git a/tests/pass-dep/shims/libc-misc.rs b/tests/pass-dep/shims/libc-misc.rs index f710daf527..c320480928 100644 --- a/tests/pass-dep/shims/libc-misc.rs +++ b/tests/pass-dep/shims/libc-misc.rs @@ -153,6 +153,8 @@ fn test_sync_file_range() { /// Tests whether each thread has its own `__errno_location`. fn test_thread_local_errno() { + #[cfg(any(target_os = "solaris", target_os = "illumos"))] + use libc::__errno as __errno_location; #[cfg(target_os = "linux")] use libc::__errno_location; #[cfg(any(target_os = "macos", target_os = "freebsd"))]