about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2024-05-16 10:43:38 +0200
committerRalf Jung <post@ralfj.de>2024-05-16 11:25:44 +0200
commit6d314f3b11f50db58974746c1c68234c26259ca8 (patch)
treed808d349fb81342d43ab012d0c3a055a6f8f6ed3
parent0334bf8520f48aedcb6ee26ab0dffd1d8452a179 (diff)
downloadrust-6d314f3b11f50db58974746c1c68234c26259ca8.tar.gz
rust-6d314f3b11f50db58974746c1c68234c26259ca8.zip
alloc now works on wasi (and some formatting)
-rwxr-xr-xsrc/tools/miri/ci/ci.sh15
-rw-r--r--src/tools/miri/src/machine.rs15
-rw-r--r--src/tools/miri/src/shims/alloc.rs26
-rw-r--r--src/tools/miri/src/shims/foreign_items.rs5
-rw-r--r--src/tools/miri/src/shims/mod.rs11
-rw-r--r--src/tools/miri/src/shims/unix/foreign_items.rs22
-rw-r--r--src/tools/miri/src/shims/wasi/foreign_items.rs34
-rw-r--r--src/tools/miri/src/shims/wasi/mod.rs1
-rw-r--r--src/tools/miri/tests/pass-dep/libc/libc-mem.rs6
-rw-r--r--src/tools/miri/tests/pass/empty_main.rs3
10 files changed, 97 insertions, 41 deletions
diff --git a/src/tools/miri/ci/ci.sh b/src/tools/miri/ci/ci.sh
index 6292d1033b6..2a6ca8f4783 100755
--- a/src/tools/miri/ci/ci.sh
+++ b/src/tools/miri/ci/ci.sh
@@ -144,16 +144,15 @@ case $HOST_TARGET in
     TEST_TARGET=arm-unknown-linux-gnueabi run_tests
     TEST_TARGET=s390x-unknown-linux-gnu run_tests # big-endian architecture of choice
     # Partially supported targets (tier 2)
-    VERY_BASIC="integer vec string btreemap" # common things we test on all of them (if they have std), requires no target-specific shims
-    BASIC="$VERY_BASIC hello hashmap alloc align" # ensures we have the shims for stdout and basic data structures
+    BASIC="empty_main integer vec string btreemap hello hashmap heap_alloc align" # ensures we have the basics: stdout/stderr, system allocator, randomness (for HashMap initialization)
     TEST_TARGET=x86_64-unknown-freebsd run_tests_minimal $BASIC panic/panic concurrency/simple atomic threadname libc-mem libc-misc libc-random libc-time fs env num_cpus
     TEST_TARGET=i686-unknown-freebsd   run_tests_minimal $BASIC panic/panic concurrency/simple atomic threadname libc-mem libc-misc libc-random libc-time fs env num_cpus
-    TEST_TARGET=x86_64-unknown-illumos run_tests_minimal $BASIC hello panic/panic concurrency/simple pthread-sync libc-mem libc-misc libc-random env
-    TEST_TARGET=x86_64-pc-solaris run_tests_minimal $BASIC hello panic/panic concurrency/simple pthread-sync libc-mem libc-misc libc-random env
-    TEST_TARGET=aarch64-linux-android  run_tests_minimal $VERY_BASIC hello panic/panic
-    TEST_TARGET=wasm32-wasi run_tests_minimal $VERY_BASIC wasm
-    TEST_TARGET=wasm32-unknown-unknown run_tests_minimal $VERY_BASIC wasm
-    TEST_TARGET=thumbv7em-none-eabihf run_tests_minimal no_std
+    TEST_TARGET=x86_64-unknown-illumos run_tests_minimal $BASIC panic/panic concurrency/simple pthread-sync libc-mem libc-misc libc-random env
+    TEST_TARGET=x86_64-pc-solaris      run_tests_minimal $BASIC panic/panic concurrency/simple pthread-sync libc-mem libc-misc libc-random env
+    TEST_TARGET=aarch64-linux-android  run_tests_minimal empty_main hello panic/panic
+    TEST_TARGET=wasm32-wasi            run_tests_minimal empty_main wasm heap_alloc libc-mem
+    TEST_TARGET=wasm32-unknown-unknown run_tests_minimal empty_main wasm
+    TEST_TARGET=thumbv7em-none-eabihf  run_tests_minimal no_std
     # Custom target JSON file
     TEST_TARGET=tests/avr.json MIRI_NO_STD=1 run_tests_minimal no_std
     ;;
diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs
index 8854b185280..6fdd126ff24 100644
--- a/src/tools/miri/src/machine.rs
+++ b/src/tools/miri/src/machine.rs
@@ -30,14 +30,13 @@ use rustc_target::abi::{Align, Size};
 use rustc_target::spec::abi::Abi;
 
 use crate::{
-    concurrency::{data_race, weak_memory},
-    shims::unix,
+    concurrency::{
+        data_race::{self, NaReadType, NaWriteType},
+        weak_memory,
+    },
     *,
 };
 
-use self::concurrency::data_race::NaReadType;
-use self::concurrency::data_race::NaWriteType;
-
 /// First real-time signal.
 /// `signal(7)` says this must be between 32 and 64 and specifies 34 or 35
 /// as typical values.
@@ -464,9 +463,9 @@ pub struct MiriMachine<'mir, 'tcx> {
     pub(crate) validate: bool,
 
     /// The table of file descriptors.
-    pub(crate) fds: unix::FdTable,
+    pub(crate) fds: shims::FdTable,
     /// The table of directory descriptors.
-    pub(crate) dirs: unix::DirTable,
+    pub(crate) dirs: shims::DirTable,
 
     /// This machine's monotone clock.
     pub(crate) clock: Clock,
@@ -641,7 +640,7 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> {
             tls: TlsData::default(),
             isolated_op: config.isolated_op,
             validate: config.validate,
-            fds: unix::FdTable::new(config.mute_stdout_stderr),
+            fds: shims::FdTable::new(config.mute_stdout_stderr),
             dirs: Default::default(),
             layouts,
             threads: ThreadManager::default(),
diff --git a/src/tools/miri/src/shims/alloc.rs b/src/tools/miri/src/shims/alloc.rs
index 1deb9a5654e..d0f36bd4757 100644
--- a/src/tools/miri/src/shims/alloc.rs
+++ b/src/tools/miri/src/shims/alloc.rs
@@ -111,6 +111,32 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
         Ok(ptr.into())
     }
 
+    fn posix_memalign(
+        &mut self,
+        memptr: &OpTy<'tcx, Provenance>,
+        align: &OpTy<'tcx, Provenance>,
+        size: &OpTy<'tcx, Provenance>,
+    ) -> InterpResult<'tcx, Scalar<Provenance>> {
+        let this = self.eval_context_mut();
+        let memptr = this.deref_pointer(memptr)?;
+        let align = this.read_target_usize(align)?;
+        let size = this.read_target_usize(size)?;
+
+        // Align must be power of 2, and also at least ptr-sized (POSIX rules).
+        // But failure to adhere to this is not UB, it's an error condition.
+        if !align.is_power_of_two() || align < this.pointer_size().bytes() {
+            Ok(this.eval_libc("EINVAL"))
+        } else {
+            let ptr = this.allocate_ptr(
+                Size::from_bytes(size),
+                Align::from_bytes(align).unwrap(),
+                MiriMemoryKind::C.into(),
+            )?;
+            this.write_pointer(ptr, &memptr)?;
+            Ok(Scalar::from_i32(0))
+        }
+    }
+
     fn free(&mut self, ptr: Pointer<Option<Provenance>>) -> InterpResult<'tcx> {
         let this = self.eval_context_mut();
         if !this.ptr_is_null(ptr)? {
diff --git a/src/tools/miri/src/shims/foreign_items.rs b/src/tools/miri/src/shims/foreign_items.rs
index d431c28d55a..a65da823e24 100644
--- a/src/tools/miri/src/shims/foreign_items.rs
+++ b/src/tools/miri/src/shims/foreign_items.rs
@@ -108,6 +108,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
         let this = self.eval_context_ref();
         match this.tcx.sess.target.os.as_ref() {
             os if this.target_os_is_unix() => shims::unix::foreign_items::is_dyn_sym(name, os),
+            "wasi" => shims::wasi::foreign_items::is_dyn_sym(name),
             "windows" => shims::windows::foreign_items::is_dyn_sym(name),
             _ => false,
         }
@@ -947,6 +948,10 @@ trait EvalContextExtPriv<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
                         shims::unix::foreign_items::EvalContextExt::emulate_foreign_item_inner(
                             this, link_name, abi, args, dest,
                         ),
+                    "wasi" =>
+                        shims::wasi::foreign_items::EvalContextExt::emulate_foreign_item_inner(
+                            this, link_name, abi, args, dest,
+                        ),
                     "windows" =>
                         shims::windows::foreign_items::EvalContextExt::emulate_foreign_item_inner(
                             this, link_name, abi, args, dest,
diff --git a/src/tools/miri/src/shims/mod.rs b/src/tools/miri/src/shims/mod.rs
index aaa3c69b92d..d9c4a2282c1 100644
--- a/src/tools/miri/src/shims/mod.rs
+++ b/src/tools/miri/src/shims/mod.rs
@@ -2,20 +2,23 @@
 
 mod alloc;
 mod backtrace;
-pub mod foreign_items;
 #[cfg(target_os = "linux")]
-pub mod native_lib;
-pub mod unix;
-pub mod windows;
+mod native_lib;
+mod unix;
+mod wasi;
+mod windows;
 mod x86;
 
 pub mod env;
 pub mod extern_static;
+pub mod foreign_items;
 pub mod os_str;
 pub mod panic;
 pub mod time;
 pub mod tls;
 
+pub use unix::{DirTable, FdTable};
+
 /// What needs to be done after emulating an item (a shim or an intrinsic) is done.
 pub enum EmulateItemResult {
     /// The caller is expected to jump to the return block.
diff --git a/src/tools/miri/src/shims/unix/foreign_items.rs b/src/tools/miri/src/shims/unix/foreign_items.rs
index 5434951d9e4..78d297d4b04 100644
--- a/src/tools/miri/src/shims/unix/foreign_items.rs
+++ b/src/tools/miri/src/shims/unix/foreign_items.rs
@@ -3,7 +3,6 @@ use std::str;
 
 use rustc_middle::ty::layout::LayoutOf;
 use rustc_span::Symbol;
-use rustc_target::abi::{Align, Size};
 use rustc_target::spec::abi::Abi;
 
 use crate::shims::alloc::EvalContextExt as _;
@@ -249,24 +248,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
 
             // Allocation
             "posix_memalign" => {
-                let [ret, align, size] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
-                let ret = this.deref_pointer(ret)?;
-                let align = this.read_target_usize(align)?;
-                let size = this.read_target_usize(size)?;
-                // Align must be power of 2, and also at least ptr-sized (POSIX rules).
-                // But failure to adhere to this is not UB, it's an error condition.
-                if !align.is_power_of_two() || align < this.pointer_size().bytes() {
-                    let einval = this.eval_libc_i32("EINVAL");
-                    this.write_int(einval, dest)?;
-                } else {
-                    let ptr = this.allocate_ptr(
-                        Size::from_bytes(size),
-                        Align::from_bytes(align).unwrap(),
-                        MiriMemoryKind::C.into(),
-                    )?;
-                    this.write_pointer(ptr, &ret)?;
-                    this.write_null(dest)?;
-                }
+                let [memptr, align, size] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let result = this.posix_memalign(memptr, align, size)?;
+                this.write_scalar(result, dest)?;
             }
 
             "mmap" => {
diff --git a/src/tools/miri/src/shims/wasi/foreign_items.rs b/src/tools/miri/src/shims/wasi/foreign_items.rs
new file mode 100644
index 00000000000..12bf0490932
--- /dev/null
+++ b/src/tools/miri/src/shims/wasi/foreign_items.rs
@@ -0,0 +1,34 @@
+use rustc_span::Symbol;
+use rustc_target::spec::abi::Abi;
+
+use crate::shims::alloc::EvalContextExt as _;
+use crate::*;
+
+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() {
+            // Allocation
+            "posix_memalign" => {
+                let [memptr, align, size] =
+                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let result = this.posix_memalign(memptr, align, size)?;
+                this.write_scalar(result, dest)?;
+            }
+
+            _ => return Ok(EmulateItemResult::NotSupported),
+        }
+        Ok(EmulateItemResult::NeedsJumping)
+    }
+}
diff --git a/src/tools/miri/src/shims/wasi/mod.rs b/src/tools/miri/src/shims/wasi/mod.rs
new file mode 100644
index 00000000000..09c6507b24f
--- /dev/null
+++ b/src/tools/miri/src/shims/wasi/mod.rs
@@ -0,0 +1 @@
+pub mod foreign_items;
diff --git a/src/tools/miri/tests/pass-dep/libc/libc-mem.rs b/src/tools/miri/tests/pass-dep/libc/libc-mem.rs
index b36fb436b57..5bd205dd085 100644
--- a/src/tools/miri/tests/pass-dep/libc/libc-mem.rs
+++ b/src/tools/miri/tests/pass-dep/libc/libc-mem.rs
@@ -226,7 +226,8 @@ fn test_memalign() {
     target_os = "windows",
     target_os = "macos",
     target_os = "illumos",
-    target_os = "solaris"
+    target_os = "solaris",
+    target_os = "wasi",
 )))]
 fn test_reallocarray() {
     unsafe {
@@ -249,7 +250,8 @@ fn main() {
         target_os = "windows",
         target_os = "macos",
         target_os = "illumos",
-        target_os = "solaris"
+        target_os = "solaris",
+        target_os = "wasi",
     )))]
     test_reallocarray();
 
diff --git a/src/tools/miri/tests/pass/empty_main.rs b/src/tools/miri/tests/pass/empty_main.rs
new file mode 100644
index 00000000000..d081b6db670
--- /dev/null
+++ b/src/tools/miri/tests/pass/empty_main.rs
@@ -0,0 +1,3 @@
+// This may look trivial, but a bunch of code runs in std before
+// `main` is called, so we are ensuring that that all works.
+fn main() {}