]> git.lizzy.rs Git - rust.git/commitdiff
Auto merge of #2221 - InfRandomness:freebsd-target-support, r=RalfJung
authorbors <bors@rust-lang.org>
Mon, 27 Jun 2022 17:40:15 +0000 (17:40 +0000)
committerbors <bors@rust-lang.org>
Mon, 27 Jun 2022 17:40:15 +0000 (17:40 +0000)
Freebsd-target-support

Implement freebsd as a target for miri

ci.sh
src/helpers.rs
src/shims/unix/dlsym.rs
src/shims/unix/foreign_items.rs
src/shims/unix/freebsd/dlsym.rs [new file with mode: 0644]
src/shims/unix/freebsd/foreign_items.rs [new file with mode: 0644]
src/shims/unix/freebsd/mod.rs [new file with mode: 0644]
src/shims/unix/linux/foreign_items.rs
src/shims/unix/mod.rs
tests/pass/libc.rs

diff --git a/ci.sh b/ci.sh
index 01b86ff2f96ba26dc6a5531873da750d0ee98e03..1fa67f52139ed923c6e4765b01e5f1fb233e0fdc 100755 (executable)
--- a/ci.sh
+++ b/ci.sh
@@ -42,6 +42,16 @@ function run_tests {
   echo
 }
 
+function run_tests_minimal {
+  if [ -n "${MIRI_TEST_TARGET+exists}" ]; then
+    echo "Testing MINIMAL foreign architecture $MIRI_TEST_TARGET: only testing $@"
+  else
+    echo "Testing MINIMAL host architecture: only testing $@"
+  fi
+
+  ./miri test --locked -- "$@"
+}
+
 # host
 run_tests
 
@@ -50,6 +60,7 @@ case $HOST_TARGET in
     MIRI_TEST_TARGET=i686-unknown-linux-gnu run_tests
     MIRI_TEST_TARGET=aarch64-apple-darwin run_tests
     MIRI_TEST_TARGET=i686-pc-windows-msvc run_tests
+    MIRI_TEST_TARGET=x86_64-unknown-freebsd run_tests_minimal hello integer vec
     ;;
   x86_64-apple-darwin)
     MIRI_TEST_TARGET=mips64-unknown-linux-gnuabi64 run_tests # big-endian architecture
index 134f556bf120456e6933d3ec43909a63a6194cb9..86823f28178871e4537aed72099f717731467fd2 100644 (file)
@@ -910,5 +910,5 @@ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
 /// Helper function used inside the shims of foreign functions to check that
 /// `target_os` is a supported UNIX OS.
 pub fn target_os_is_unix(target_os: &str) -> bool {
-    matches!(target_os, "linux" | "macos")
+    matches!(target_os, "linux" | "macos" | "freebsd")
 }
index 578ae488a98ea117f86d1e041f2c0affb3d0d1b5..e1f819fb85671c1fc5fe75a45a17252d96e83e38 100644 (file)
@@ -2,6 +2,7 @@
 use rustc_target::spec::abi::Abi;
 
 use crate::*;
+use shims::unix::freebsd::dlsym as freebsd;
 use shims::unix::linux::dlsym as linux;
 use shims::unix::macos::dlsym as macos;
 
@@ -9,6 +10,7 @@
 pub enum Dlsym {
     Linux(linux::Dlsym),
     MacOs(macos::Dlsym),
+    FreeBSD(freebsd::Dlsym),
 }
 
 impl Dlsym {
@@ -18,6 +20,7 @@ pub fn from_str<'tcx>(name: &str, target_os: &str) -> InterpResult<'tcx, Option<
         Ok(match target_os {
             "linux" => linux::Dlsym::from_str(name)?.map(Dlsym::Linux),
             "macos" => macos::Dlsym::from_str(name)?.map(Dlsym::MacOs),
+            "freebsd" => freebsd::Dlsym::from_str(name)?.map(Dlsym::FreeBSD),
             _ => unreachable!(),
         })
     }
@@ -40,6 +43,8 @@ fn call_dlsym(
         match dlsym {
             Dlsym::Linux(dlsym) => linux::EvalContextExt::call_dlsym(this, dlsym, args, dest, ret),
             Dlsym::MacOs(dlsym) => macos::EvalContextExt::call_dlsym(this, dlsym, args, dest, ret),
+            Dlsym::FreeBSD(dlsym) =>
+                freebsd::EvalContextExt::call_dlsym(this, dlsym, args, dest, ret),
         }
     }
 }
index d002ab75b9bed685de3cd316feb89e929143c8f2..d0c93ef4cdaf3c793e5a7f2d4eaa8931ca4f2a03 100644 (file)
@@ -461,6 +461,28 @@ fn emulate_foreign_item_by_name(
                 this.write_null(dest)?;
             }
 
+            // Querying system information
+            "pthread_attr_getstack" => {
+                // We don't support "pthread_attr_setstack", so we just pretend all stacks have the same values here. Hence we can mostly ignore the input `attr_place`.
+                let [attr_place, addr_place, size_place] =
+                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let _attr_place = this.deref_operand(attr_place)?;
+                let addr_place = this.deref_operand(addr_place)?;
+                let size_place = this.deref_operand(size_place)?;
+
+                this.write_scalar(
+                    Scalar::from_uint(STACK_ADDR, this.pointer_size()),
+                    &addr_place.into(),
+                )?;
+                this.write_scalar(
+                    Scalar::from_uint(STACK_SIZE, this.pointer_size()),
+                    &size_place.into(),
+                )?;
+
+                // Return success (`0`).
+                this.write_null(dest)?;
+            }
+
             | "signal"
             | "sigaltstack"
             if this.frame_in_std() => {
@@ -485,6 +507,7 @@ fn emulate_foreign_item_by_name(
                 match this.tcx.sess.target.os.as_ref() {
                     "linux" => return shims::unix::linux::foreign_items::EvalContextExt::emulate_foreign_item_by_name(this, link_name, abi, args, dest, ret),
                     "macos" => return shims::unix::macos::foreign_items::EvalContextExt::emulate_foreign_item_by_name(this, link_name, abi, args, dest, ret),
+                    "freebsd" => return shims::unix::freebsd::foreign_items::EvalContextExt::emulate_foreign_item_by_name(this, link_name, abi, args, dest, ret),
                     _ => unreachable!(),
                 }
             }
diff --git a/src/shims/unix/freebsd/dlsym.rs b/src/shims/unix/freebsd/dlsym.rs
new file mode 100644 (file)
index 0000000..18347d2
--- /dev/null
@@ -0,0 +1,32 @@
+use rustc_middle::mir;
+
+use crate::*;
+
+#[derive(Debug, Copy, Clone)]
+#[allow(non_camel_case_types)]
+pub enum Dlsym {}
+
+impl Dlsym {
+    // Returns an error for unsupported symbols, and None if this symbol
+    // should become a NULL pointer (pretend it does not exist).
+    pub fn from_str<'tcx>(name: &str) -> InterpResult<'tcx, Option<Dlsym>> {
+        throw_unsup_format!("unsupported FreeBSD dlsym: {}", name)
+    }
+}
+
+impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {}
+pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> {
+    fn call_dlsym(
+        &mut self,
+        dlsym: Dlsym,
+        _args: &[OpTy<'tcx, Tag>],
+        _dest: &PlaceTy<'tcx, Tag>,
+        ret: Option<mir::BasicBlock>,
+    ) -> InterpResult<'tcx> {
+        let this = self.eval_context_mut();
+        let _ret = ret.expect("we don't support any diverging dlsym");
+        assert!(this.tcx.sess.target.os == "freebsd");
+
+        match dlsym {}
+    }
+}
diff --git a/src/shims/unix/freebsd/foreign_items.rs b/src/shims/unix/freebsd/foreign_items.rs
new file mode 100644 (file)
index 0000000..cad1192
--- /dev/null
@@ -0,0 +1,31 @@
+use rustc_middle::mir;
+use rustc_span::Symbol;
+use rustc_target::spec::abi::Abi;
+
+use crate::*;
+use shims::foreign_items::EmulateByNameResult;
+
+impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {}
+
+pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> {
+    fn emulate_foreign_item_by_name(
+        &mut self,
+        link_name: Symbol,
+        abi: Abi,
+        args: &[OpTy<'tcx, Tag>],
+        dest: &PlaceTy<'tcx, Tag>,
+        _ret: mir::BasicBlock,
+    ) -> InterpResult<'tcx, EmulateByNameResult<'mir, 'tcx>> {
+        let this = self.eval_context_mut();
+        match link_name.as_str() {
+            // Linux's `pthread_getattr_np` equivalent
+            "pthread_attr_get_np" if this.frame_in_std() => {
+                let [_thread, _attr] =
+                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                this.write_null(dest)?;
+            }
+            _ => return Ok(EmulateByNameResult::NotSupported),
+        }
+        Ok(EmulateByNameResult::NeedsJumping)
+    }
+}
diff --git a/src/shims/unix/freebsd/mod.rs b/src/shims/unix/freebsd/mod.rs
new file mode 100644 (file)
index 0000000..434f5f3
--- /dev/null
@@ -0,0 +1,2 @@
+pub mod dlsym;
+pub mod foreign_items;
index ab3f39147c60fa0a55613753dbdf07e830f65d77..48abe9bf08c33d1658cfa05d706521ace2bca5d7 100644 (file)
@@ -80,28 +80,6 @@ fn emulate_foreign_item_by_name(
                 this.write_scalar(Scalar::from_i32(result), dest)?;
             }
 
-            // Querying system information
-            "pthread_attr_getstack" => {
-                // We don't support "pthread_attr_setstack", so we just pretend all stacks have the same values here.
-                let [attr_place, addr_place, size_place] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
-                this.deref_operand(attr_place)?;
-                let addr_place = this.deref_operand(addr_place)?;
-                let size_place = this.deref_operand(size_place)?;
-
-                this.write_scalar(
-                    Scalar::from_uint(STACK_ADDR, this.pointer_size()),
-                    &addr_place.into(),
-                )?;
-                this.write_scalar(
-                    Scalar::from_uint(STACK_SIZE, this.pointer_size()),
-                    &size_place.into(),
-                )?;
-
-                // Return success (`0`).
-                this.write_null(dest)?;
-            }
-
             // Threading
             "prctl" => {
                 // prctl is variadic. (It is not documented like that in the manpage, but defined like that in the libc crate.)
index f40dfaefb92ac2ca26d1443fed44831eb3fff95f..8e8c70bbd0faf4fa3f4068382311eacc7f18efca 100644 (file)
@@ -5,6 +5,7 @@
 mod sync;
 mod thread;
 
+mod freebsd;
 mod linux;
 mod macos;
 
index f97b9dd2b9eaa2ca50b502418626967c0e6a88ff..e73e796449cc54efb44a3a6ddb5c7d0dd604baa1 100644 (file)
@@ -5,14 +5,14 @@
 
 extern crate libc;
 
-#[cfg(target_os = "linux")]
+#[cfg(any(target_os = "linux", target_os = "freebsd"))]
 fn tmp() -> std::path::PathBuf {
     std::env::var("MIRI_TEMP")
         .map(std::path::PathBuf::from)
         .unwrap_or_else(|_| std::env::temp_dir())
 }
 
-#[cfg(target_os = "linux")]
+#[cfg(any(target_os = "linux", target_os = "freebsd"))]
 fn test_posix_fadvise() {
     use std::convert::TryInto;
     use std::fs::{remove_file, File};
@@ -42,7 +42,7 @@ fn test_posix_fadvise() {
     assert_eq!(result, 0);
 }
 
-#[cfg(target_os = "linux")]
+#[cfg(any(target_os = "linux", target_os = "freebsd"))]
 fn test_sync_file_range() {
     use std::fs::{remove_file, File};
     use std::io::Write;
@@ -208,7 +208,7 @@ fn test_rwlock_libc_static_initializer() {
 /// Test whether the `prctl` shim correctly sets the thread name.
 ///
 /// Note: `prctl` exists only on Linux.
-#[cfg(target_os = "linux")]
+#[cfg(any(target_os = "linux", target_os = "freebsd"))]
 fn test_prctl_thread_name() {
     use libc::c_long;
     use std::ffi::CString;
@@ -277,7 +277,7 @@ fn test_thread_local_errno() {
 }
 
 /// Tests whether clock support exists at all
-#[cfg(target_os = "linux")]
+#[cfg(any(target_os = "linux", target_os = "freebsd"))]
 fn test_clocks() {
     let mut tp = std::mem::MaybeUninit::<libc::timespec>::uninit();
     let is_error = unsafe { libc::clock_gettime(libc::CLOCK_REALTIME, tp.as_mut_ptr()) };
@@ -291,10 +291,10 @@ fn test_clocks() {
 }
 
 fn main() {
-    #[cfg(target_os = "linux")]
+    #[cfg(any(target_os = "linux", target_os = "freebsd"))]
     test_posix_fadvise();
 
-    #[cfg(target_os = "linux")]
+    #[cfg(any(target_os = "linux", target_os = "freebsd"))]
     test_sync_file_range();
 
     test_mutex_libc_init_recursive();
@@ -302,14 +302,14 @@ fn main() {
     test_mutex_libc_init_errorcheck();
     test_rwlock_libc_static_initializer();
 
-    #[cfg(target_os = "linux")]
+    #[cfg(any(target_os = "linux", target_os = "freebsd"))]
     test_mutex_libc_static_initializer_recursive();
 
-    #[cfg(target_os = "linux")]
+    #[cfg(any(target_os = "linux", target_os = "freebsd"))]
     test_prctl_thread_name();
 
     test_thread_local_errno();
 
-    #[cfg(target_os = "linux")]
+    #[cfg(any(target_os = "linux", target_os = "freebsd"))]
     test_clocks();
 }