about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/tools/miri/src/shims/backtrace.rs8
-rw-r--r--src/tools/miri/src/shims/unix/linux/foreign_items.rs2
-rw-r--r--src/tools/miri/src/shims/unix/linux/sync.rs42
3 files changed, 17 insertions, 35 deletions
diff --git a/src/tools/miri/src/shims/backtrace.rs b/src/tools/miri/src/shims/backtrace.rs
index 25afda4edc8..ae2cdaa8d57 100644
--- a/src/tools/miri/src/shims/backtrace.rs
+++ b/src/tools/miri/src/shims/backtrace.rs
@@ -5,6 +5,7 @@ use rustc_span::{BytePos, Loc, Symbol, hygiene};
 use rustc_target::abi::Size;
 use rustc_target::spec::abi::Abi;
 
+use crate::helpers::check_min_arg_count;
 use crate::*;
 
 impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
@@ -39,11 +40,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
         let this = self.eval_context_mut();
         let tcx = this.tcx;
 
-        let flags = if let Some(flags_op) = args.first() {
-            this.read_scalar(flags_op)?.to_u64()?
-        } else {
-            throw_ub_format!("expected at least 1 argument")
-        };
+        let [flags] = check_min_arg_count("miri_get_backtrace", args)?;
+        let flags = this.read_scalar(flags)?.to_u64()?;
 
         let mut data = Vec::new();
         for frame in this.active_thread_stack().iter().rev() {
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 6c8345652c2..e73bde1ddb6 100644
--- a/src/tools/miri/src/shims/unix/linux/foreign_items.rs
+++ b/src/tools/miri/src/shims/unix/linux/foreign_items.rs
@@ -150,7 +150,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                     }
                     // `futex` is used by some synchronization primitives.
                     num if num == sys_futex => {
-                        futex(this, &args[1..], dest)?;
+                        futex(this, args, dest)?;
                     }
                     num if num == sys_eventfd2 => {
                         let [_, initval, flags] =
diff --git a/src/tools/miri/src/shims/unix/linux/sync.rs b/src/tools/miri/src/shims/unix/linux/sync.rs
index 5833ec64fc6..941011bfac6 100644
--- a/src/tools/miri/src/shims/unix/linux/sync.rs
+++ b/src/tools/miri/src/shims/unix/linux/sync.rs
@@ -1,7 +1,8 @@
+use crate::helpers::check_min_arg_count;
 use crate::*;
 
 /// Implementation of the SYS_futex syscall.
-/// `args` is the arguments *after* the syscall number.
+/// `args` is the arguments *including* the syscall number.
 pub fn futex<'tcx>(
     this: &mut MiriInterpCx<'tcx>,
     args: &[OpTy<'tcx>],
@@ -15,12 +16,7 @@ pub fn futex<'tcx>(
     // may or may not be left out from the `syscall()` call.
     // Therefore we don't use `check_arg_count` here, but only check for the
     // number of arguments to fall within a range.
-    let [addr, op, val, ..] = args else {
-        throw_ub_format!(
-            "incorrect number of arguments for `futex` syscall: got {}, expected at least 3",
-            args.len()
-        );
-    };
+    let [_, addr, op, val] = check_min_arg_count("`syscall(SYS_futex, ...)`", args)?;
 
     // The first three arguments (after the syscall number itself) are the same to all futex operations:
     //     (int *addr, int op, int val).
@@ -54,24 +50,16 @@ pub fn futex<'tcx>(
         op if op & !futex_realtime == futex_wait || op & !futex_realtime == futex_wait_bitset => {
             let wait_bitset = op & !futex_realtime == futex_wait_bitset;
 
-            let bitset = if wait_bitset {
-                let [_, _, _, timeout, uaddr2, bitset, ..] = args else {
-                    throw_ub_format!(
-                        "incorrect number of arguments for `futex` syscall with `op=FUTEX_WAIT_BITSET`: got {}, expected at least 6",
-                        args.len()
-                    );
-                };
+            let (timeout, bitset) = if wait_bitset {
+                let [_, _, _, _, timeout, uaddr2, bitset] =
+                    check_min_arg_count("`syscall(SYS_futex, FUTEX_WAIT_BITSET, ...)`", args)?;
                 let _timeout = this.read_pointer(timeout)?;
                 let _uaddr2 = this.read_pointer(uaddr2)?;
-                this.read_scalar(bitset)?.to_u32()?
+                (timeout, this.read_scalar(bitset)?.to_u32()?)
             } else {
-                if args.len() < 4 {
-                    throw_ub_format!(
-                        "incorrect number of arguments for `futex` syscall with `op=FUTEX_WAIT`: got {}, expected at least 4",
-                        args.len()
-                    );
-                }
-                u32::MAX
+                let [_, _, _, _, timeout] =
+                    check_min_arg_count("`syscall(SYS_futex, FUTEX_WAIT, ...)`", args)?;
+                (timeout, u32::MAX)
             };
 
             if bitset == 0 {
@@ -80,7 +68,7 @@ pub fn futex<'tcx>(
                 return interp_ok(());
             }
 
-            let timeout = this.deref_pointer_as(&args[3], this.libc_ty_layout("timespec"))?;
+            let timeout = this.deref_pointer_as(timeout, this.libc_ty_layout("timespec"))?;
             let timeout = if this.ptr_is_null(timeout.ptr())? {
                 None
             } else {
@@ -183,12 +171,8 @@ pub fn futex<'tcx>(
         // Same as FUTEX_WAKE, but allows you to specify a bitset to select which threads to wake up.
         op if op == futex_wake || op == futex_wake_bitset => {
             let bitset = if op == futex_wake_bitset {
-                let [_, _, _, timeout, uaddr2, bitset, ..] = args else {
-                    throw_ub_format!(
-                        "incorrect number of arguments for `futex` syscall with `op=FUTEX_WAKE_BITSET`: got {}, expected at least 6",
-                        args.len()
-                    );
-                };
+                let [_, _, _, _, timeout, uaddr2, bitset] =
+                    check_min_arg_count("`syscall(SYS_futex, FUTEX_WAKE_BITSET, ...)`", args)?;
                 let _timeout = this.read_pointer(timeout)?;
                 let _uaddr2 = this.read_pointer(uaddr2)?;
                 this.read_scalar(bitset)?.to_u32()?