about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDavid Carlier <devnexen@gmail.com>2024-11-23 11:55:26 +0000
committerDavid Carlier <devnexen@gmail.com>2024-11-24 09:22:58 +0000
commitbb55f5239a237f0b37973d49a357b4443446d5f0 (patch)
tree4b14e0a4fd14e5fa377b73c18b8b5d40ccc8956f
parent6a4aa9a36db2f23f4a017f1bc226a88a2bd8846f (diff)
downloadrust-bb55f5239a237f0b37973d49a357b4443446d5f0.tar.gz
rust-bb55f5239a237f0b37973d49a357b4443446d5f0.zip
follow-up on #4052, making a miri evaluation context fn for strerror_r.
-rw-r--r--src/tools/miri/src/shims/unix/android/foreign_items.rs9
-rw-r--r--src/tools/miri/src/shims/unix/foreign_items.rs54
-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.rs14
-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.rs2
-rw-r--r--src/tools/miri/tests/pass-dep/libc/libc-strerror_r.rs16
7 files changed, 62 insertions, 50 deletions
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 6c5a61437af..80ad40e1624 100644
--- a/src/tools/miri/src/shims/unix/android/foreign_items.rs
+++ b/src/tools/miri/src/shims/unix/android/foreign_items.rs
@@ -2,7 +2,6 @@ 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::*;
 
@@ -21,14 +20,6 @@ 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 a50ac1be77e..5594bd4e790 100644
--- a/src/tools/miri/src/shims/unix/foreign_items.rs
+++ b/src/tools/miri/src/shims/unix/foreign_items.rs
@@ -68,6 +68,30 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
         throw_unsup_format!("unimplemented sysconf name: {}", name)
     }
 
+    fn strerror_r(
+        &mut self,
+        errnum: &OpTy<'tcx>,
+        buf: &OpTy<'tcx>,
+        buflen: &OpTy<'tcx>,
+    ) -> InterpResult<'tcx, Scalar> {
+        let this = self.eval_context_mut();
+
+        let errnum = this.read_scalar(errnum)?;
+        let buf = this.read_pointer(buf)?;
+        let buflen = this.read_target_usize(buflen)?;
+        let error = this.try_errnum_to_io_error(errnum)?;
+        let formatted = match error {
+            Some(err) => format!("{err}"),
+            None => format!("<unknown errnum in strerror_r: {errnum}>"),
+        };
+        let (complete, _) = this.write_os_str_to_c_str(OsStr::new(&formatted), buf, buflen)?;
+        if complete {
+            interp_ok(Scalar::from_i32(0))
+        } else {
+            interp_ok(Scalar::from_i32(this.eval_libc_i32("ERANGE")))
+        }
+    }
+
     fn emulate_foreign_item_inner(
         &mut self,
         link_name: Symbol,
@@ -113,6 +137,13 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 this.write_scalar(result, 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)?;
+            }
+
             // File descriptors
             "read" => {
                 let [fd, buf, count] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
@@ -724,21 +755,6 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 // We do not support forking, so there is nothing to do here.
                 this.write_null(dest)?;
             }
-            "strerror_r" | "__xpg_strerror_r" => {
-                let [errnum, buf, buflen] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
-                let errnum = this.read_scalar(errnum)?;
-                let buf = this.read_pointer(buf)?;
-                let buflen = this.read_target_usize(buflen)?;
-
-                let error = this.try_errnum_to_io_error(errnum)?;
-                let formatted = match error {
-                    Some(err) => format!("{err}"),
-                    None => format!("<unknown errnum in strerror_r: {errnum}>"),
-                };
-                let (complete, _) = this.write_os_str_to_c_str(OsStr::new(&formatted), buf, buflen)?;
-                let ret = if complete { 0 } else { this.eval_libc_i32("ERANGE") };
-                this.write_int(ret, dest)?;
-            }
             "getentropy" => {
                 // This function is non-standard but exists with the same signature and behavior on
                 // Linux, macOS, FreeBSD and Solaris/Illumos.
@@ -766,6 +782,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                     this.write_null(dest)?;
                 }
             }
+
+            "strerror_r" => {
+                let [errnum, buf, buflen] =
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
+                let result = this.strerror_r(errnum, buf, buflen)?;
+                this.write_scalar(result, dest)?;
+            }
+
             "getrandom" => {
                 // This function is non-standard but exists with the same signature and behavior on
                 // Linux, FreeBSD and Solaris/Illumos.
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 ddea9ecc294..1346d8de7ea 100644
--- a/src/tools/miri/src/shims/unix/freebsd/foreign_items.rs
+++ b/src/tools/miri/src/shims/unix/freebsd/foreign_items.rs
@@ -1,7 +1,6 @@
 use rustc_abi::ExternAbi;
 use rustc_span::Symbol;
 
-use crate::shims::unix::foreign_items::EvalContextExt as _;
 use crate::shims::unix::*;
 use crate::*;
 
@@ -76,14 +75,6 @@ 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 75b0afcac00..810e8d3340a 100644
--- a/src/tools/miri/src/shims/unix/linux/foreign_items.rs
+++ b/src/tools/miri/src/shims/unix/linux/foreign_items.rs
@@ -125,14 +125,6 @@ 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)?;
@@ -152,6 +144,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 let ptr = this.mremap(old_address, old_size, new_size, flags)?;
                 this.write_scalar(ptr, dest)?;
             }
+            "__xpg_strerror_r" => {
+                let [errnum, buf, buflen] =
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
+                let result = this.strerror_r(errnum, buf, buflen)?;
+                this.write_scalar(result, dest)?;
+            }
             "__errno_location" => {
                 let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let errno_place = this.last_error_place()?;
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 7f67a2cab36..003025916cd 100644
--- a/src/tools/miri/src/shims/unix/macos/foreign_items.rs
+++ b/src/tools/miri/src/shims/unix/macos/foreign_items.rs
@@ -2,7 +2,6 @@ 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::*;
 
@@ -168,13 +167,6 @@ 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 2eeab38e35c..1bbd25617e5 100644
--- a/src/tools/miri/src/shims/unix/solarish/foreign_items.rs
+++ b/src/tools/miri/src/shims/unix/solarish/foreign_items.rs
@@ -113,7 +113,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 this.write_null(dest)?;
             }
 
-            "sysconf" | "__sysconf_xpg7" => {
+            "__sysconf_xpg7" => {
                 let [val] =
                     this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let result = this.sysconf(val)?;
diff --git a/src/tools/miri/tests/pass-dep/libc/libc-strerror_r.rs b/src/tools/miri/tests/pass-dep/libc/libc-strerror_r.rs
new file mode 100644
index 00000000000..09885ce839d
--- /dev/null
+++ b/src/tools/miri/tests/pass-dep/libc/libc-strerror_r.rs
@@ -0,0 +1,16 @@
+//@ignore-target: windows # Supported only on unixes
+
+fn main() {
+    unsafe {
+        let mut buf = vec![0u8; 32];
+        assert_eq!(libc::strerror_r(libc::EPERM, buf.as_mut_ptr().cast(), buf.len()), 0);
+        let mut buf2 = vec![0u8; 64];
+        assert_eq!(libc::strerror_r(-1i32, buf2.as_mut_ptr().cast(), buf2.len()), 0);
+        // This buffer is deliberately too small so this triggers ERANGE.
+        let mut buf3 = vec![0u8; 2];
+        assert_eq!(
+            libc::strerror_r(libc::E2BIG, buf3.as_mut_ptr().cast(), buf3.len()),
+            libc::ERANGE
+        );
+    }
+}