miri/shims/unix/linux_like/
syscall.rs1use rustc_abi::CanonAbi;
2use rustc_middle::ty::Ty;
3use rustc_span::Symbol;
4use rustc_target::callconv::FnAbi;
5
6use crate::shims::sig::check_min_vararg_count;
7use crate::shims::unix::env::EvalContextExt;
8use crate::shims::unix::linux_like::eventfd::EvalContextExt as _;
9use crate::shims::unix::linux_like::sync::futex;
10use crate::shims::unix::socket::EvalContextExt as _;
11use crate::*;
12
13pub fn syscall<'tcx>(
14 ecx: &mut MiriInterpCx<'tcx>,
15 link_name: Symbol,
16 abi: &FnAbi<'tcx, Ty<'tcx>>,
17 args: &[OpTy<'tcx>],
18 dest: &MPlaceTy<'tcx>,
19) -> InterpResult<'tcx> {
20 let ([op], varargs) = ecx.check_shim_sig_variadic_lenient(abi, CanonAbi::C, link_name, args)?;
21 let sys_getrandom = ecx.eval_libc("SYS_getrandom").to_target_usize(ecx)?;
27 let sys_futex = ecx.eval_libc("SYS_futex").to_target_usize(ecx)?;
28 let sys_eventfd2 = ecx.eval_libc("SYS_eventfd2").to_target_usize(ecx)?;
29 let sys_gettid = ecx.eval_libc("SYS_gettid").to_target_usize(ecx)?;
30 let sys_accept4 = ecx.eval_libc("SYS_accept4").to_target_usize(ecx)?;
31
32 match ecx.read_target_usize(op)? {
33 num if num == sys_getrandom => {
36 let [ptr, len, flags] = check_min_vararg_count("syscall(SYS_getrandom, ...)", varargs)?;
39
40 let ptr = ecx.read_pointer(ptr)?;
41 let len = ecx.read_target_usize(len)?;
42 let _flags = ecx.read_scalar(flags)?.to_i32()?;
46
47 ecx.gen_random(ptr, len)?;
48 ecx.write_scalar(Scalar::from_target_usize(len, ecx), dest)?;
49 }
50 num if num == sys_futex => {
52 futex(ecx, varargs, dest)?;
53 }
54 num if num == sys_eventfd2 => {
55 let [initval, flags] = check_min_vararg_count("syscall(SYS_evetfd2, ...)", varargs)?;
56
57 let result = ecx.eventfd(initval, flags)?;
58 ecx.write_int(result.to_i32()?, dest)?;
59 }
60 num if num == sys_gettid => {
61 let result = ecx.unix_gettid("SYS_gettid")?;
62 ecx.write_int(result.to_u32()?, dest)?;
63 }
64 num if num == sys_accept4 => {
65 let [socket, address, address_len, flags] =
67 check_min_vararg_count("syscall(SYS_accept4, ...)", varargs)?;
68 ecx.accept4(socket, address, address_len, Some(flags), dest)?;
69 }
70 num => {
71 throw_unsup_format!("syscall: unsupported syscall number {num}");
72 }
73 };
74
75 interp_ok(())
76}