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