From f6fe15fd0358b129c046444b0144d3968874517f 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. --- src/shims/unix/foreign_items.rs | 5 +- src/shims/unix/mod.rs | 1 + src/shims/unix/solarish/foreign_items.rs | 70 ++++++++++++++++++++++ src/shims/unix/solarish/mod.rs | 1 + tests/pass-dep/shims/libc-misc.rs | 2 + tests/pass-dep/shims/pthread-threadname.rs | 2 +- 6 files changed, 79 insertions(+), 2 deletions(-) create mode 100644 src/shims/unix/solarish/foreign_items.rs create mode 100644 src/shims/unix/solarish/mod.rs diff --git a/src/shims/unix/foreign_items.rs b/src/shims/unix/foreign_items.rs index bd299aaa12..0c498a32de 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, }, } @@ -593,7 +595,7 @@ 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") { + 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 @@ -750,6 +752,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..584527f568 --- /dev/null +++ b/src/shims/unix/solarish/foreign_items.rs @@ -0,0 +1,70 @@ +use rustc_span::Symbol; +use rustc_target::spec::abi::Abi; + +use crate::*; +use shims::foreign_items::EmulateForeignItemResult; +use shims::unix::thread::EvalContextExt as _; + +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: &PlaceTy<'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_setname_np" => { + let [thread, name] = + this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + // The thread name can have a size up to PTHREAD_MAX_NAMELEN_NP(32) + // https://illumos.org/man/3C/pthread_getname_np + let max_len = 32; + let res = this.pthread_setname_np( + this.read_scalar(thread)?, + this.read_scalar(name)?, + max_len, + )?; + this.write_scalar(res, dest)?; + } + "pthread_getname_np" => { + let [thread, name, len] = + this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let res = this.pthread_getname_np( + this.read_scalar(thread)?, + this.read_scalar(name)?, + this.read_scalar(len)?, + )?; + this.write_scalar(res, dest)?; + } + "getrandom" => { + let [ptr, len, flags] = + this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let ptr = this.read_pointer(ptr)?; + let len = this.read_target_usize(len)?; + let _flags = this.read_scalar(flags)?.to_i32()?; + // GRND_RANDOM, nor GRND_NONBLOCK have any effect on the PRNG. + // https://smartos.org/man/2/getrandom + this.gen_random(ptr, len)?; + this.write_scalar(Scalar::from_target_usize(len, this), 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/tests/pass-dep/shims/libc-misc.rs b/tests/pass-dep/shims/libc-misc.rs index f710daf527..4000c61ca4 100644 --- a/tests/pass-dep/shims/libc-misc.rs +++ b/tests/pass-dep/shims/libc-misc.rs @@ -157,6 +157,8 @@ fn test_thread_local_errno() { use libc::__errno_location; #[cfg(any(target_os = "macos", target_os = "freebsd"))] use libc::__error as __errno_location; + #[cfg(any(target_os = "solaris", target_os = "illumos"))] + use libc::__errno as __errno_location; unsafe { *__errno_location() = 0xBEEF; diff --git a/tests/pass-dep/shims/pthread-threadname.rs b/tests/pass-dep/shims/pthread-threadname.rs index bc782044d4..32b0ed925a 100644 --- a/tests/pass-dep/shims/pthread-threadname.rs +++ b/tests/pass-dep/shims/pthread-threadname.rs @@ -10,7 +10,7 @@ fn main() { .collect::(); fn set_thread_name(name: &CStr) -> i32 { - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "solaris", target_os = "illumos"))] return unsafe { libc::pthread_setname_np(libc::pthread_self(), name.as_ptr().cast()) }; #[cfg(target_os = "freebsd")] unsafe {