1+ use  crate :: helpers:: check_min_arg_count; 
12use  crate :: * ; 
23
34/// Implementation of the SYS_futex syscall. 
4- /// `args` is the arguments *after * the syscall number. 
5+ /// `args` is the arguments *including * the syscall number. 
56pub  fn  futex < ' tcx > ( 
67    this :  & mut  MiriInterpCx < ' tcx > , 
78    args :  & [ OpTy < ' tcx > ] , 
@@ -15,12 +16,7 @@ pub fn futex<'tcx>(
1516    // may or may not be left out from the `syscall()` call. 
1617    // Therefore we don't use `check_arg_count` here, but only check for the 
1718    // number of arguments to fall within a range. 
18-     let  [ addr,  op,  val,  ..]  = args else  { 
19-         throw_ub_format ! ( 
20-             "incorrect number of arguments for `futex` syscall: got {}, expected at least 3" , 
21-             args. len( ) 
22-         ) ; 
23-     } ; 
19+     let  [ _,  addr,  op,  val]  = check_min_arg_count ( "`syscall(SYS_futex, ...)`" ,  args) ?; 
2420
2521    // The first three arguments (after the syscall number itself) are the same to all futex operations: 
2622    //     (int *addr, int op, int val). 
@@ -54,24 +50,16 @@ pub fn futex<'tcx>(
5450        op if  op &  !futex_realtime == futex_wait || op &  !futex_realtime == futex_wait_bitset => { 
5551            let  wait_bitset = op &  !futex_realtime == futex_wait_bitset; 
5652
57-             let  bitset = if  wait_bitset { 
58-                 let  [ _,  _,  _,  timeout,  uaddr2,  bitset,  ..]  = args else  { 
59-                     throw_ub_format ! ( 
60-                         "incorrect number of arguments for `futex` syscall with `op=FUTEX_WAIT_BITSET`: got {}, expected at least 6" , 
61-                         args. len( ) 
62-                     ) ; 
63-                 } ; 
53+             let  ( timeout,  bitset)  = if  wait_bitset { 
54+                 let  [ _,  _,  _,  _,  timeout,  uaddr2,  bitset]  =
55+                     check_min_arg_count ( "`syscall(SYS_futex, FUTEX_WAIT_BITSET, ...)`" ,  args) ?; 
6456                let  _timeout = this. read_pointer ( timeout) ?; 
6557                let  _uaddr2 = this. read_pointer ( uaddr2) ?; 
66-                 this. read_scalar ( bitset) ?. to_u32 ( ) ?
58+                 ( timeout ,   this. read_scalar ( bitset) ?. to_u32 ( ) ?) 
6759            }  else  { 
68-                 if  args. len ( )  < 4  { 
69-                     throw_ub_format ! ( 
70-                         "incorrect number of arguments for `futex` syscall with `op=FUTEX_WAIT`: got {}, expected at least 4" , 
71-                         args. len( ) 
72-                     ) ; 
73-                 } 
74-                 u32:: MAX 
60+                 let  [ _,  _,  _,  _,  timeout]  =
61+                     check_min_arg_count ( "`syscall(SYS_futex, FUTEX_WAIT, ...)`" ,  args) ?; 
62+                 ( timeout,  u32:: MAX ) 
7563            } ; 
7664
7765            if  bitset == 0  { 
@@ -80,7 +68,7 @@ pub fn futex<'tcx>(
8068                return  interp_ok ( ( ) ) ; 
8169            } 
8270
83-             let  timeout = this. deref_pointer_as ( & args [ 3 ] ,  this. libc_ty_layout ( "timespec" ) ) ?; 
71+             let  timeout = this. deref_pointer_as ( timeout ,  this. libc_ty_layout ( "timespec" ) ) ?; 
8472            let  timeout = if  this. ptr_is_null ( timeout. ptr ( ) ) ? { 
8573                None 
8674            }  else  { 
@@ -183,12 +171,8 @@ pub fn futex<'tcx>(
183171        // Same as FUTEX_WAKE, but allows you to specify a bitset to select which threads to wake up. 
184172        op if  op == futex_wake || op == futex_wake_bitset => { 
185173            let  bitset = if  op == futex_wake_bitset { 
186-                 let  [ _,  _,  _,  timeout,  uaddr2,  bitset,  ..]  = args else  { 
187-                     throw_ub_format ! ( 
188-                         "incorrect number of arguments for `futex` syscall with `op=FUTEX_WAKE_BITSET`: got {}, expected at least 6" , 
189-                         args. len( ) 
190-                     ) ; 
191-                 } ; 
174+                 let  [ _,  _,  _,  _,  timeout,  uaddr2,  bitset]  =
175+                     check_min_arg_count ( "`syscall(SYS_futex, FUTEX_WAKE_BITSET, ...)`" ,  args) ?; 
192176                let  _timeout = this. read_pointer ( timeout) ?; 
193177                let  _uaddr2 = this. read_pointer ( uaddr2) ?; 
194178                this. read_scalar ( bitset) ?. to_u32 ( ) ?
0 commit comments