about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDavid Carlier <devnexen@gmail.com>2023-12-01 23:41:07 +0000
committerDavid Carlier <devnexen@gmail.com>2024-05-05 12:52:47 +0100
commitb4011a08e8a7753ba241b947f4bedf7bba98cc77 (patch)
tree5744a5d5568fcd0225f8afa4ca02f640901587b3
parente3fe30d82868d2bc47b43d6a90538aafd09cc17f (diff)
downloadrust-b4011a08e8a7753ba241b947f4bedf7bba98cc77.tar.gz
rust-b4011a08e8a7753ba241b947f4bedf7bba98cc77.zip
illumos support.
-rw-r--r--src/tools/miri/README.md1
-rwxr-xr-xsrc/tools/miri/ci/ci.sh3
-rw-r--r--src/tools/miri/src/concurrency/thread.rs7
-rw-r--r--src/tools/miri/src/shims/unix/foreign_items.rs8
-rw-r--r--src/tools/miri/src/shims/unix/mod.rs1
-rw-r--r--src/tools/miri/src/shims/unix/solarish/foreign_items.rs41
-rw-r--r--src/tools/miri/src/shims/unix/solarish/mod.rs1
-rw-r--r--src/tools/miri/src/shims/unix/sync.rs62
-rw-r--r--src/tools/miri/src/shims/unix/thread.rs2
9 files changed, 102 insertions, 24 deletions
diff --git a/src/tools/miri/README.md b/src/tools/miri/README.md
index f92cc088e0f..5b3e2a588b4 100644
--- a/src/tools/miri/README.md
+++ b/src/tools/miri/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.
+  - `illumos`: maintained by @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/src/tools/miri/ci/ci.sh b/src/tools/miri/ci/ci.sh
index d3dee0de617..8b7d23621a8 100755
--- a/src/tools/miri/ci/ci.sh
+++ b/src/tools/miri/ci/ci.sh
@@ -146,6 +146,9 @@ 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 pthread-sync
+	# TODO fix solaris stack guard
+    # MIRI_TEST_TARGET=x86_64-pc-solaris run_tests_minimal $VERY_BASIC hello panic/panic pthread-sync
     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/tools/miri/src/concurrency/thread.rs b/src/tools/miri/src/concurrency/thread.rs
index 0116bd0281a..6953ce81c5e 100644
--- a/src/tools/miri/src/concurrency/thread.rs
+++ b/src/tools/miri/src/concurrency/thread.rs
@@ -78,6 +78,13 @@ impl TryFrom<u64> for ThreadId {
     }
 }
 
+impl TryFrom<i128> for ThreadId {
+    type Error = TryFromIntError;
+    fn try_from(id: i128) -> Result<Self, Self::Error> {
+        u32::try_from(id).map(Self)
+    }
+}
+
 impl From<u32> for ThreadId {
     fn from(id: u32) -> Self {
         Self(id)
diff --git a/src/tools/miri/src/shims/unix/foreign_items.rs b/src/tools/miri/src/shims/unix/foreign_items.rs
index 90e0406f099..3d3a510c4a2 100644
--- a/src/tools/miri/src/shims/unix/foreign_items.rs
+++ b/src/tools/miri/src/shims/unix/foreign_items.rs
@@ -13,6 +13,7 @@ use crate::*;
 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;
 
 pub fn is_dyn_sym(name: &str, target_os: &str) -> bool {
     match name {
@@ -29,6 +30,7 @@ pub 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,
             },
     }
@@ -591,8 +593,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
@@ -608,6 +610,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)?;
@@ -730,6 +733,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(EmulateItemResult::NotSupported),
                 };
             }
diff --git a/src/tools/miri/src/shims/unix/mod.rs b/src/tools/miri/src/shims/unix/mod.rs
index bede2fbd389..6dee30d895c 100644
--- a/src/tools/miri/src/shims/unix/mod.rs
+++ b/src/tools/miri/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/tools/miri/src/shims/unix/solarish/foreign_items.rs b/src/tools/miri/src/shims/unix/solarish/foreign_items.rs
new file mode 100644
index 00000000000..5bf4a7621d0
--- /dev/null
+++ b/src/tools/miri/src/shims/unix/solarish/foreign_items.rs
@@ -0,0 +1,41 @@
+use rustc_span::Symbol;
+use rustc_target::spec::abi::Abi;
+
+use crate::shims::unix::*;
+use crate::*;
+use shims::EmulateItemResult;
+
+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, EmulateItemResult> {
+        let this = self.eval_context_mut();
+        match link_name.as_str() {
+            // 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(EmulateItemResult::NotSupported),
+        }
+        Ok(EmulateItemResult::NeedsJumping)
+    }
+}
diff --git a/src/tools/miri/src/shims/unix/solarish/mod.rs b/src/tools/miri/src/shims/unix/solarish/mod.rs
new file mode 100644
index 00000000000..09c6507b24f
--- /dev/null
+++ b/src/tools/miri/src/shims/unix/solarish/mod.rs
@@ -0,0 +1 @@
+pub mod foreign_items;
diff --git a/src/tools/miri/src/shims/unix/sync.rs b/src/tools/miri/src/shims/unix/sync.rs
index 9c096760415..2c9208deb3c 100644
--- a/src/tools/miri/src/shims/unix/sync.rs
+++ b/src/tools/miri/src/shims/unix/sync.rs
@@ -68,11 +68,20 @@ fn mutexattr_set_kind<'mir, 'tcx: 'mir>(
 // (the kind has to be at this particular offset for compatibility with Linux's static initializer
 // macros, e.g. PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP.)
 
+#[inline]
+fn mutex_id_offset<'mir, 'tcx: 'mir>(ecx: &MiriInterpCx<'mir, 'tcx>) -> u64 {
+    if matches!(&*ecx.tcx.sess.target.os, "macos") { 4 } else { 0 }
+}
+
 fn mutex_get_id<'mir, 'tcx: 'mir>(
     ecx: &mut MiriInterpCx<'mir, 'tcx>,
     mutex_op: &OpTy<'tcx, Provenance>,
 ) -> InterpResult<'tcx, MutexId> {
-    ecx.mutex_get_or_create_id(mutex_op, ecx.libc_ty_layout("pthread_mutex_t"), 4)
+    ecx.mutex_get_or_create_id(
+        mutex_op,
+        ecx.libc_ty_layout("pthread_mutex_t"),
+        mutex_id_offset(ecx),
+    )
 }
 
 fn mutex_reset_id<'mir, 'tcx: 'mir>(
@@ -81,7 +90,7 @@ fn mutex_reset_id<'mir, 'tcx: 'mir>(
 ) -> InterpResult<'tcx, ()> {
     ecx.deref_pointer_and_write(
         mutex_op,
-        4,
+        mutex_id_offset(ecx),
         Scalar::from_i32(0),
         ecx.libc_ty_layout("pthread_mutex_t"),
         ecx.machine.layouts.u32,
@@ -124,13 +133,20 @@ fn mutex_set_kind<'mir, 'tcx: 'mir>(
 // (need to avoid this because it is set by static initializer macros)
 // bytes 4-7: rwlock id as u32 or 0 if id is not assigned yet.
 
-const RWLOCK_ID_OFFSET: u64 = 4;
+#[inline]
+fn rwlock_id_offset<'mir, 'tcx: 'mir>(ecx: &MiriInterpCx<'mir, 'tcx>) -> u64 {
+    if matches!(&*ecx.tcx.sess.target.os, "macos") { 4 } else { 0 }
+}
 
 fn rwlock_get_id<'mir, 'tcx: 'mir>(
     ecx: &mut MiriInterpCx<'mir, 'tcx>,
     rwlock_op: &OpTy<'tcx, Provenance>,
 ) -> InterpResult<'tcx, RwLockId> {
-    ecx.rwlock_get_or_create_id(rwlock_op, ecx.libc_ty_layout("pthread_rwlock_t"), RWLOCK_ID_OFFSET)
+    ecx.rwlock_get_or_create_id(
+        rwlock_op,
+        ecx.libc_ty_layout("pthread_rwlock_t"),
+        rwlock_id_offset(ecx),
+    )
 }
 
 // pthread_condattr_t
@@ -177,14 +193,18 @@ fn condattr_set_clock_id<'mir, 'tcx: 'mir>(
 // bytes 4-7: the conditional variable id as u32 or 0 if id is not assigned yet.
 // bytes 8-11: the clock id constant as i32
 
-const CONDVAR_ID_OFFSET: u64 = 4;
 const CONDVAR_CLOCK_OFFSET: u64 = 8;
 
+#[inline]
+fn cond_id_offset<'mir, 'tcx: 'mir>(ecx: &MiriInterpCx<'mir, 'tcx>) -> u64 {
+    if matches!(&*ecx.tcx.sess.target.os, "macos") { 4 } else { 0 }
+}
+
 fn cond_get_id<'mir, 'tcx: 'mir>(
     ecx: &mut MiriInterpCx<'mir, 'tcx>,
     cond_op: &OpTy<'tcx, Provenance>,
 ) -> InterpResult<'tcx, CondvarId> {
-    ecx.condvar_get_or_create_id(cond_op, ecx.libc_ty_layout("pthread_cond_t"), CONDVAR_ID_OFFSET)
+    ecx.condvar_get_or_create_id(cond_op, ecx.libc_ty_layout("pthread_cond_t"), cond_id_offset(ecx))
 }
 
 fn cond_reset_id<'mir, 'tcx: 'mir>(
@@ -193,7 +213,7 @@ fn cond_reset_id<'mir, 'tcx: 'mir>(
 ) -> InterpResult<'tcx, ()> {
     ecx.deref_pointer_and_write(
         cond_op,
-        CONDVAR_ID_OFFSET,
+        cond_id_offset(ecx),
         Scalar::from_i32(0),
         ecx.libc_ty_layout("pthread_cond_t"),
         ecx.machine.layouts.u32,
@@ -287,7 +307,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
@@ -376,7 +396,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
@@ -537,7 +557,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
@@ -562,7 +582,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
@@ -586,7 +606,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
@@ -623,7 +643,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
@@ -647,7 +667,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
@@ -673,7 +693,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
@@ -704,7 +724,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
@@ -728,9 +748,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
         let this = self.eval_context_mut();
 
         // Does not exist on macOS!
-        if !matches!(&*this.tcx.sess.target.os, "linux") {
+        if !matches!(&*this.tcx.sess.target.os, "linux" | "solaris" | "illumos") {
             throw_unsup_format!(
-                "`pthread_condattr_init` is not supported on {}",
+                "`pthread_condattr_setclock` is not supported on {}",
                 this.tcx.sess.target.os
             );
         }
@@ -756,9 +776,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
         let this = self.eval_context_mut();
 
         // Does not exist on macOS!
-        if !matches!(&*this.tcx.sess.target.os, "linux") {
+        if !matches!(&*this.tcx.sess.target.os, "linux" | "solaris" | "illumos") {
             throw_unsup_format!(
-                "`pthread_condattr_init` is not supported on {}",
+                "`pthread_condattr_getclock` is not supported on {}",
                 this.tcx.sess.target.os
             );
         }
@@ -793,7 +813,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/src/tools/miri/src/shims/unix/thread.rs b/src/tools/miri/src/shims/unix/thread.rs
index 2a56cd35dcb..7f814e080ff 100644
--- a/src/tools/miri/src/shims/unix/thread.rs
+++ b/src/tools/miri/src/shims/unix/thread.rs
@@ -42,7 +42,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
             throw_unsup_format!("Miri supports pthread_join only with retval==NULL");
         }
 
-        let thread_id = this.read_target_usize(thread)?;
+        let thread_id = this.read_scalar(thread)?.to_int(this.libc_ty_layout("pthread_t").size)?;
         this.join_thread_exclusive(thread_id.try_into().expect("thread ID should fit in u32"))?;
 
         Ok(0)