about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2024-11-23 08:11:09 +0000
committerGitHub <noreply@github.com>2024-11-23 08:11:09 +0000
commit6a4aa9a36db2f23f4a017f1bc226a88a2bd8846f (patch)
treeb1f21b03e5c6aa9b3427dabd75e9fe6827fb85cf
parentfa93f358d151812e2684a758aee133c70b0ff1fa (diff)
parent004edb27cf319b3d844f3bce397aa1079235a390 (diff)
downloadrust-6a4aa9a36db2f23f4a017f1bc226a88a2bd8846f.tar.gz
rust-6a4aa9a36db2f23f4a017f1bc226a88a2bd8846f.zip
Merge pull request #4052 from devnexen/gh4050
sysconf interception fix for solarish systems.
-rwxr-xr-xsrc/tools/miri/ci/ci.sh2
-rw-r--r--src/tools/miri/src/shims/unix/android/foreign_items.rs9
-rw-r--r--src/tools/miri/src/shims/unix/foreign_items.rs58
-rw-r--r--src/tools/miri/src/shims/unix/freebsd/foreign_items.rs9
-rw-r--r--src/tools/miri/src/shims/unix/linux/foreign_items.rs9
-rw-r--r--src/tools/miri/src/shims/unix/macos/foreign_items.rs8
-rw-r--r--src/tools/miri/src/shims/unix/solarish/foreign_items.rs8
-rw-r--r--src/tools/miri/tests/pass-dep/libc/libc-sysconf.rs17
8 files changed, 90 insertions, 30 deletions
diff --git a/src/tools/miri/ci/ci.sh b/src/tools/miri/ci/ci.sh
index 9b020d029a6..0356d7ecf10 100755
--- a/src/tools/miri/ci/ci.sh
+++ b/src/tools/miri/ci/ci.sh
@@ -153,7 +153,7 @@ case $HOST_TARGET in
     TEST_TARGET=x86_64-unknown-freebsd run_tests_minimal $BASIC $UNIX time hashmap random threadname pthread fs libc-pipe
     TEST_TARGET=i686-unknown-freebsd   run_tests_minimal $BASIC $UNIX time hashmap random threadname pthread fs libc-pipe
     TEST_TARGET=x86_64-unknown-illumos run_tests_minimal $BASIC $UNIX time hashmap random thread sync available-parallelism tls libc-pipe
-    # TEST_TARGET=x86_64-pc-solaris      run_tests_minimal $BASIC $UNIX time hashmap random thread sync available-parallelism tls libc-pipe
+    TEST_TARGET=x86_64-pc-solaris      run_tests_minimal $BASIC $UNIX time hashmap random thread sync available-parallelism tls libc-pipe
     TEST_TARGET=aarch64-linux-android  run_tests_minimal $BASIC $UNIX time hashmap random sync threadname pthread
     TEST_TARGET=wasm32-wasip2          run_tests_minimal $BASIC wasm
     TEST_TARGET=wasm32-unknown-unknown run_tests_minimal no_std empty_main wasm # this target doesn't really have std
diff --git a/src/tools/miri/src/shims/unix/android/foreign_items.rs b/src/tools/miri/src/shims/unix/android/foreign_items.rs
index 80ad40e1624..6c5a61437af 100644
--- a/src/tools/miri/src/shims/unix/android/foreign_items.rs
+++ b/src/tools/miri/src/shims/unix/android/foreign_items.rs
@@ -2,6 +2,7 @@ use rustc_abi::ExternAbi;
 use rustc_span::Symbol;
 
 use crate::shims::unix::android::thread::prctl;
+use crate::shims::unix::foreign_items::EvalContextExt as _;
 use crate::shims::unix::linux::syscall::syscall;
 use crate::*;
 
@@ -20,6 +21,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
     ) -> InterpResult<'tcx, EmulateItemResult> {
         let this = self.eval_context_mut();
         match link_name.as_str() {
+            // Querying system information
+            "sysconf" => {
+                let [val] =
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
+                let result = this.sysconf(val)?;
+                this.write_scalar(result, dest)?;
+            }
+
             // Miscellaneous
             "__errno" => {
                 let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
diff --git a/src/tools/miri/src/shims/unix/foreign_items.rs b/src/tools/miri/src/shims/unix/foreign_items.rs
index 55202a08149..a50ac1be77e 100644
--- a/src/tools/miri/src/shims/unix/foreign_items.rs
+++ b/src/tools/miri/src/shims/unix/foreign_items.rs
@@ -39,6 +39,35 @@ pub fn is_dyn_sym(name: &str, target_os: &str) -> bool {
 
 impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
 pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
+    // Querying system information
+    fn sysconf(&mut self, val: &OpTy<'tcx>) -> InterpResult<'tcx, Scalar> {
+        let this = self.eval_context_mut();
+
+        let name = this.read_scalar(val)?.to_i32()?;
+        // FIXME: Which of these are POSIX, and which are GNU/Linux?
+        // At least the names seem to all also exist on macOS.
+        let sysconfs: &[(&str, fn(&MiriInterpCx<'_>) -> Scalar)] = &[
+            ("_SC_PAGESIZE", |this| Scalar::from_int(this.machine.page_size, this.pointer_size())),
+            ("_SC_PAGE_SIZE", |this| Scalar::from_int(this.machine.page_size, this.pointer_size())),
+            ("_SC_NPROCESSORS_CONF", |this| {
+                Scalar::from_int(this.machine.num_cpus, this.pointer_size())
+            }),
+            ("_SC_NPROCESSORS_ONLN", |this| {
+                Scalar::from_int(this.machine.num_cpus, this.pointer_size())
+            }),
+            // 512 seems to be a reasonable default. The value is not critical, in
+            // the sense that getpwuid_r takes and checks the buffer length.
+            ("_SC_GETPW_R_SIZE_MAX", |this| Scalar::from_int(512, this.pointer_size())),
+        ];
+        for &(sysconf_name, value) in sysconfs {
+            let sysconf_name = this.eval_libc_i32(sysconf_name);
+            if sysconf_name == name {
+                return interp_ok(value(this));
+            }
+        }
+        throw_unsup_format!("unimplemented sysconf name: {}", name)
+    }
+
     fn emulate_foreign_item_inner(
         &mut self,
         link_name: Symbol,
@@ -393,35 +422,6 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 }
             }
 
-            // Querying system information
-            "sysconf" => {
-                let [name] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
-                let name = this.read_scalar(name)?.to_i32()?;
-                // FIXME: Which of these are POSIX, and which are GNU/Linux?
-                // At least the names seem to all also exist on macOS.
-                let sysconfs: &[(&str, fn(&MiriInterpCx<'_>) -> Scalar)] = &[
-                    ("_SC_PAGESIZE", |this| Scalar::from_int(this.machine.page_size, this.pointer_size())),
-                    ("_SC_NPROCESSORS_CONF", |this| Scalar::from_int(this.machine.num_cpus, this.pointer_size())),
-                    ("_SC_NPROCESSORS_ONLN", |this| Scalar::from_int(this.machine.num_cpus, this.pointer_size())),
-                    // 512 seems to be a reasonable default. The value is not critical, in
-                    // the sense that getpwuid_r takes and checks the buffer length.
-                    ("_SC_GETPW_R_SIZE_MAX", |this| Scalar::from_int(512, this.pointer_size()))
-                ];
-                let mut result = None;
-                for &(sysconf_name, value) in sysconfs {
-                    let sysconf_name = this.eval_libc_i32(sysconf_name);
-                    if sysconf_name == name {
-                        result = Some(value(this));
-                        break;
-                    }
-                }
-                if let Some(result) = result {
-                    this.write_scalar(result, dest)?;
-                } else {
-                    throw_unsup_format!("unimplemented sysconf name: {}", name)
-                }
-            }
-
             // Thread-local storage
             "pthread_key_create" => {
                 let [key, dtor] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
diff --git a/src/tools/miri/src/shims/unix/freebsd/foreign_items.rs b/src/tools/miri/src/shims/unix/freebsd/foreign_items.rs
index 1346d8de7ea..ddea9ecc294 100644
--- a/src/tools/miri/src/shims/unix/freebsd/foreign_items.rs
+++ b/src/tools/miri/src/shims/unix/freebsd/foreign_items.rs
@@ -1,6 +1,7 @@
 use rustc_abi::ExternAbi;
 use rustc_span::Symbol;
 
+use crate::shims::unix::foreign_items::EvalContextExt as _;
 use crate::shims::unix::*;
 use crate::*;
 
@@ -75,6 +76,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 this.write_scalar(result, dest)?;
             }
 
+            // Querying system information
+            "sysconf" => {
+                let [val] =
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
+                let result = this.sysconf(val)?;
+                this.write_scalar(result, dest)?;
+            }
+
             // Miscellaneous
             "__error" => {
                 let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
diff --git a/src/tools/miri/src/shims/unix/linux/foreign_items.rs b/src/tools/miri/src/shims/unix/linux/foreign_items.rs
index 85f0d6e1330..75b0afcac00 100644
--- a/src/tools/miri/src/shims/unix/linux/foreign_items.rs
+++ b/src/tools/miri/src/shims/unix/linux/foreign_items.rs
@@ -6,6 +6,7 @@ use self::shims::unix::linux::eventfd::EvalContextExt as _;
 use self::shims::unix::linux::mem::EvalContextExt as _;
 use self::shims::unix::linux::syscall::syscall;
 use crate::machine::{SIGRTMAX, SIGRTMIN};
+use crate::shims::unix::foreign_items::EvalContextExt as _;
 use crate::shims::unix::*;
 use crate::*;
 
@@ -124,6 +125,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 this.write_scalar(result, dest)?;
             }
 
+            // Querying system information
+            "sysconf" => {
+                let [val] =
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
+                let result = this.sysconf(val)?;
+                this.write_scalar(result, dest)?;
+            }
+
             // Dynamically invoked syscalls
             "syscall" => {
                 syscall(this, link_name, abi, args, dest)?;
diff --git a/src/tools/miri/src/shims/unix/macos/foreign_items.rs b/src/tools/miri/src/shims/unix/macos/foreign_items.rs
index 003025916cd..7f67a2cab36 100644
--- a/src/tools/miri/src/shims/unix/macos/foreign_items.rs
+++ b/src/tools/miri/src/shims/unix/macos/foreign_items.rs
@@ -2,6 +2,7 @@ use rustc_abi::ExternAbi;
 use rustc_span::Symbol;
 
 use super::sync::EvalContextExt as _;
+use crate::shims::unix::foreign_items::EvalContextExt as _;
 use crate::shims::unix::*;
 use crate::*;
 
@@ -167,6 +168,13 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 this.write_scalar(stack_size, dest)?;
             }
 
+            "sysconf" => {
+                let [val] =
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
+                let result = this.sysconf(val)?;
+                this.write_scalar(result, dest)?;
+            }
+
             // Threading
             "pthread_setname_np" => {
                 let [name] =
diff --git a/src/tools/miri/src/shims/unix/solarish/foreign_items.rs b/src/tools/miri/src/shims/unix/solarish/foreign_items.rs
index 526b64cff69..2eeab38e35c 100644
--- a/src/tools/miri/src/shims/unix/solarish/foreign_items.rs
+++ b/src/tools/miri/src/shims/unix/solarish/foreign_items.rs
@@ -1,6 +1,7 @@
 use rustc_abi::ExternAbi;
 use rustc_span::Symbol;
 
+use crate::shims::unix::foreign_items::EvalContextExt as _;
 use crate::shims::unix::*;
 use crate::*;
 
@@ -112,6 +113,13 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 this.write_null(dest)?;
             }
 
+            "sysconf" | "__sysconf_xpg7" => {
+                let [val] =
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
+                let result = this.sysconf(val)?;
+                this.write_scalar(result, dest)?;
+            }
+
             _ => return interp_ok(EmulateItemResult::NotSupported),
         }
         interp_ok(EmulateItemResult::NeedsReturn)
diff --git a/src/tools/miri/tests/pass-dep/libc/libc-sysconf.rs b/src/tools/miri/tests/pass-dep/libc/libc-sysconf.rs
new file mode 100644
index 00000000000..34d5b1e38a6
--- /dev/null
+++ b/src/tools/miri/tests/pass-dep/libc/libc-sysconf.rs
@@ -0,0 +1,17 @@
+//@ignore-target: windows # Supported only on unixes
+
+fn test_sysconfbasic() {
+    unsafe {
+        let ncpus = libc::sysconf(libc::_SC_NPROCESSORS_CONF);
+        assert!(ncpus >= 1);
+        let psz = libc::sysconf(libc::_SC_PAGESIZE);
+        assert!(psz % 4096 == 0);
+        // note that in reality it can return -1 (no hard limit) on some platforms.
+        let gwmax = libc::sysconf(libc::_SC_GETPW_R_SIZE_MAX);
+        assert!(gwmax >= 512);
+    }
+}
+
+fn main() {
+    test_sysconfbasic();
+}