miri/shims/unix/linux_like/
syscall.rsuse rustc_middle::ty::Ty;
use rustc_span::Symbol;
use rustc_target::callconv::{Conv, FnAbi};
use crate::helpers::check_min_arg_count;
use crate::shims::unix::linux_like::eventfd::EvalContextExt as _;
use crate::shims::unix::linux_like::sync::futex;
use crate::*;
pub fn syscall<'tcx>(
ecx: &mut MiriInterpCx<'tcx>,
link_name: Symbol,
abi: &FnAbi<'tcx, Ty<'tcx>>,
args: &[OpTy<'tcx>],
dest: &MPlaceTy<'tcx>,
) -> InterpResult<'tcx> {
ecx.check_abi_and_shim_symbol_clash(abi, Conv::C, link_name)?;
let sys_getrandom = ecx.eval_libc("SYS_getrandom").to_target_usize(ecx)?;
let sys_futex = ecx.eval_libc("SYS_futex").to_target_usize(ecx)?;
let sys_eventfd2 = ecx.eval_libc("SYS_eventfd2").to_target_usize(ecx)?;
let [op] = check_min_arg_count("syscall", args)?;
match ecx.read_target_usize(op)? {
num if num == sys_getrandom => {
let [_, ptr, len, flags] = check_min_arg_count("syscall(SYS_getrandom, ...)", args)?;
let ptr = ecx.read_pointer(ptr)?;
let len = ecx.read_target_usize(len)?;
let _flags = ecx.read_scalar(flags)?.to_i32()?;
ecx.gen_random(ptr, len)?;
ecx.write_scalar(Scalar::from_target_usize(len, ecx), dest)?;
}
num if num == sys_futex => {
futex(ecx, args, dest)?;
}
num if num == sys_eventfd2 => {
let [_, initval, flags] = check_min_arg_count("syscall(SYS_evetfd2, ...)", args)?;
let result = ecx.eventfd(initval, flags)?;
ecx.write_int(result.to_i32()?, dest)?;
}
num => {
throw_unsup_format!("syscall: unsupported syscall number {num}");
}
};
interp_ok(())
}