about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-11-16 17:52:07 +0000
committerbors <bors@rust-lang.org>2023-11-16 17:52:07 +0000
commit0b6b44f4ca3a132b4b9cbf1ac40ac0e25abbdf0b (patch)
treee0d45cf6f038eb4ea3eb1d79aeb262dd76f6af81
parent7df74ebad1b91e589bc53590aa20407c0bb3895f (diff)
parentc6acc058c0cb260b75cacdbe72e653770815f7d6 (diff)
downloadrust-0b6b44f4ca3a132b4b9cbf1ac40ac0e25abbdf0b.tar.gz
rust-0b6b44f4ca3a132b4b9cbf1ac40ac0e25abbdf0b.zip
Auto merge of #3166 - devnexen:reallocarray, r=RalfJung
reallocarray shim linux/freebsd support proposal.
-rwxr-xr-xsrc/tools/miri/ci.sh2
-rw-r--r--src/tools/miri/src/shims/unix/foreign_items.rs31
-rw-r--r--src/tools/miri/tests/pass-dep/shims/libc-reallocarray.rs16
3 files changed, 48 insertions, 1 deletions
diff --git a/src/tools/miri/ci.sh b/src/tools/miri/ci.sh
index 5c6351d0192..dd57319a54c 100755
--- a/src/tools/miri/ci.sh
+++ b/src/tools/miri/ci.sh
@@ -108,7 +108,7 @@ case $HOST_TARGET in
     MIRI_TEST_TARGET=aarch64-unknown-linux-gnu run_tests
     MIRI_TEST_TARGET=aarch64-apple-darwin run_tests
     MIRI_TEST_TARGET=i686-pc-windows-gnu run_tests
-    MIRI_TEST_TARGET=x86_64-unknown-freebsd run_tests_minimal hello integer vec panic/panic concurrency/simple pthreads libc-getentropy libc-getrandom atomic env/var
+    MIRI_TEST_TARGET=x86_64-unknown-freebsd run_tests_minimal hello integer vec panic/panic concurrency/simple pthreads libc-getentropy libc-getrandom libc-reallocarray atomic env/var
     MIRI_TEST_TARGET=aarch64-linux-android run_tests_minimal hello integer vec panic/panic
     MIRI_TEST_TARGET=wasm32-wasi run_tests_minimal no_std integer strings wasm
     MIRI_TEST_TARGET=wasm32-unknown-unknown run_tests_minimal no_std integer strings wasm
diff --git a/src/tools/miri/src/shims/unix/foreign_items.rs b/src/tools/miri/src/shims/unix/foreign_items.rs
index f993afa67ad..d155623eb7b 100644
--- a/src/tools/miri/src/shims/unix/foreign_items.rs
+++ b/src/tools/miri/src/shims/unix/foreign_items.rs
@@ -252,6 +252,37 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
                 this.write_scalar(result, dest)?;
             }
 
+            "reallocarray" => {
+                // Currently this function does not exist on all Unixes, e.g. on macOS.
+                if !matches!(&*this.tcx.sess.target.os, "linux" | "freebsd") {
+                    throw_unsup_format!(
+                        "`reallocarray` is not supported on {}",
+                        this.tcx.sess.target.os
+                    );
+                }
+                let [ptr, nmemb, size] =
+                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let ptr = this.read_pointer(ptr)?;
+                let nmemb = this.read_target_usize(nmemb)?;
+                let size = this.read_target_usize(size)?;
+                // reallocarray checks a possible overflow and returns ENOMEM
+                // if that happens.
+                //
+                // Linux: https://www.unix.com/man-page/linux/3/reallocarray/
+                // FreeBSD: https://man.freebsd.org/cgi/man.cgi?query=reallocarray
+                match nmemb.checked_mul(size) {
+                    None => {
+                        let einval = this.eval_libc("ENOMEM");
+                        this.set_last_error(einval)?;
+                        this.write_null(dest)?;
+                    }
+                    Some(len) => {
+                        let res = this.realloc(ptr, len, MiriMemoryKind::C)?;
+                        this.write_pointer(res, dest)?;
+                    }
+                }
+            }
+
             // Dynamic symbol loading
             "dlsym" => {
                 let [handle, symbol] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
diff --git a/src/tools/miri/tests/pass-dep/shims/libc-reallocarray.rs b/src/tools/miri/tests/pass-dep/shims/libc-reallocarray.rs
new file mode 100644
index 00000000000..29a3a590852
--- /dev/null
+++ b/src/tools/miri/tests/pass-dep/shims/libc-reallocarray.rs
@@ -0,0 +1,16 @@
+//@ignore-target-windows: no libc
+//@ignore-target-apple: no support (yet)
+
+use core::ptr;
+
+fn main() {
+    unsafe {
+        let mut p = libc::reallocarray(ptr::null_mut(), 4096, 2);
+        assert!(!p.is_null());
+        libc::free(p);
+        p = libc::malloc(16);
+        let r = libc::reallocarray(p, 2, 32);
+        assert!(!r.is_null());
+        libc::free(r);
+    }
+}