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 3722cc2f3cad4..2a72004378e06 100644 --- a/src/tools/miri/src/shims/unix/linux/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/linux/foreign_items.rs @@ -122,6 +122,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let sys_getrandom = this.eval_libc("SYS_getrandom").to_target_usize(this)?; let sys_futex = this.eval_libc("SYS_futex").to_target_usize(this)?; + let sys_eventfd2 = this.eval_libc("SYS_eventfd2").to_target_usize(this)?; if args.is_empty() { throw_ub_format!( @@ -155,6 +156,17 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { id if id == sys_futex => { futex(this, &args[1..], dest)?; } + id if id == sys_eventfd2 => { + let [_, initval, flags, ..] = args else { + throw_ub_format!( + "incorrect number of arguments for `eventfd2` syscall: got {}, expected at least 3", + args.len() + ); + }; + + let result = this.eventfd(initval, flags)?; + this.write_int(result.to_i32()?, dest)?; + } id => { this.handle_unsupported_foreign_item(format!( "can't execute syscall with ID {id}" diff --git a/src/tools/miri/tests/pass-dep/libc/libc-eventfd.rs b/src/tools/miri/tests/pass-dep/libc/libc-eventfd.rs index 1d08419465889..c92d9c3fe7095 100644 --- a/src/tools/miri/tests/pass-dep/libc/libc-eventfd.rs +++ b/src/tools/miri/tests/pass-dep/libc/libc-eventfd.rs @@ -10,6 +10,7 @@ use std::thread; fn main() { test_read_write(); test_race(); + test_syscall(); } fn read_bytes(fd: i32, buf: &mut [u8; N]) -> i32 { @@ -109,3 +110,11 @@ fn test_race() { thread::yield_now(); thread1.join().unwrap(); } + +// This is a test for calling eventfd2 through a syscall. +fn test_syscall() { + let initval = 0 as libc::c_uint; + let flags = (libc::EFD_CLOEXEC | libc::EFD_NONBLOCK) as libc::c_int; + let fd = unsafe { libc::syscall(libc::SYS_eventfd2, initval, flags) }; + assert_ne!(fd, -1); +}