miri/shims/unix/android/
foreign_items.rs

1use rustc_abi::CanonAbi;
2use rustc_middle::ty::Ty;
3use rustc_span::Symbol;
4use rustc_target::callconv::FnAbi;
5
6use crate::shims::unix::android::thread::prctl;
7use crate::shims::unix::env::EvalContextExt as _;
8use crate::shims::unix::linux_like::epoll::EvalContextExt as _;
9use crate::shims::unix::linux_like::eventfd::EvalContextExt as _;
10use crate::shims::unix::linux_like::syscall::syscall;
11use crate::*;
12
13pub fn is_dyn_sym(name: &str) -> bool {
14    matches!(name, "gettid")
15}
16
17impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
18pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
19    fn emulate_foreign_item_inner(
20        &mut self,
21        link_name: Symbol,
22        abi: &FnAbi<'tcx, Ty<'tcx>>,
23        args: &[OpTy<'tcx>],
24        dest: &MPlaceTy<'tcx>,
25    ) -> InterpResult<'tcx, EmulateItemResult> {
26        let this = self.eval_context_mut();
27        match link_name.as_str() {
28            // epoll, eventfd
29            "epoll_create1" => {
30                let [flag] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?;
31                let result = this.epoll_create1(flag)?;
32                this.write_scalar(result, dest)?;
33            }
34            "epoll_ctl" => {
35                let [epfd, op, fd, event] =
36                    this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?;
37                let result = this.epoll_ctl(epfd, op, fd, event)?;
38                this.write_scalar(result, dest)?;
39            }
40            "epoll_wait" => {
41                let [epfd, events, maxevents, timeout] =
42                    this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?;
43                this.epoll_wait(epfd, events, maxevents, timeout, dest)?;
44            }
45            "eventfd" => {
46                let [val, flag] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?;
47                let result = this.eventfd(val, flag)?;
48                this.write_scalar(result, dest)?;
49            }
50
51            // Miscellaneous
52            "__errno" => {
53                let [] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?;
54                let errno_place = this.last_error_place()?;
55                this.write_scalar(errno_place.to_ref(this).to_scalar(), dest)?;
56            }
57
58            "gettid" => {
59                let [] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?;
60                let result = this.unix_gettid(link_name.as_str())?;
61                this.write_scalar(result, dest)?;
62            }
63
64            // Dynamically invoked syscalls
65            "syscall" => syscall(this, link_name, abi, args, dest)?,
66
67            // Threading
68            "prctl" => prctl(this, link_name, abi, args, dest)?,
69
70            _ => return interp_ok(EmulateItemResult::NotSupported),
71        }
72        interp_ok(EmulateItemResult::NeedsReturn)
73    }
74}