miri/shims/unix/solarish/
foreign_items.rs1use rustc_abi::CanonAbi;
2use rustc_middle::ty::Ty;
3use rustc_span::Symbol;
4use rustc_target::callconv::FnAbi;
5
6use crate::shims::unix::foreign_items::EvalContextExt as _;
7use crate::shims::unix::linux_like::epoll::EvalContextExt as _;
8use crate::shims::unix::linux_like::eventfd::EvalContextExt as _;
9use crate::shims::unix::*;
10use crate::*;
11
12pub fn is_dyn_sym(name: &str) -> bool {
13 matches!(name, "pthread_setname_np")
14}
15
16impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
17pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
18 fn emulate_foreign_item_inner(
19 &mut self,
20 link_name: Symbol,
21 abi: &FnAbi<'tcx, Ty<'tcx>>,
22 args: &[OpTy<'tcx>],
23 dest: &MPlaceTy<'tcx>,
24 ) -> InterpResult<'tcx, EmulateItemResult> {
25 let this = self.eval_context_mut();
26 match link_name.as_str() {
27 "epoll_create1" => {
29 this.assert_target_os("illumos", "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 this.assert_target_os("illumos", "epoll_ctl");
36 let [epfd, op, fd, event] =
37 this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?;
38 let result = this.epoll_ctl(epfd, op, fd, event)?;
39 this.write_scalar(result, dest)?;
40 }
41 "epoll_wait" => {
42 this.assert_target_os("illumos", "epoll_wait");
43 let [epfd, events, maxevents, timeout] =
44 this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?;
45 this.epoll_wait(epfd, events, maxevents, timeout, dest)?;
46 }
47 "eventfd" => {
48 this.assert_target_os("illumos", "eventfd");
49 let [val, flag] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?;
50 let result = this.eventfd(val, flag)?;
51 this.write_scalar(result, dest)?;
52 }
53
54 "pthread_setname_np" => {
56 let [thread, name] =
57 this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?;
58 let max_len = 32;
61 let res = match this.pthread_setname_np(
63 this.read_scalar(thread)?,
64 this.read_scalar(name)?,
65 max_len,
66 false,
67 )? {
68 ThreadNameResult::Ok => Scalar::from_u32(0),
69 ThreadNameResult::NameTooLong => this.eval_libc("ERANGE"),
70 ThreadNameResult::ThreadNotFound => this.eval_libc("ESRCH"),
71 };
72 this.write_scalar(res, dest)?;
73 }
74 "pthread_getname_np" => {
75 let [thread, name, len] =
76 this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?;
77 let res = match this.pthread_getname_np(
79 this.read_scalar(thread)?,
80 this.read_scalar(name)?,
81 this.read_scalar(len)?,
82 false,
83 )? {
84 ThreadNameResult::Ok => Scalar::from_u32(0),
85 ThreadNameResult::NameTooLong => this.eval_libc("ERANGE"),
86 ThreadNameResult::ThreadNotFound => this.eval_libc("ESRCH"),
87 };
88 this.write_scalar(res, dest)?;
89 }
90
91 "stat" | "stat64" => {
93 let [path, buf] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?;
94 let result = this.macos_fbsd_solarish_stat(path, buf)?;
95 this.write_scalar(result, dest)?;
96 }
97 "lstat" | "lstat64" => {
98 let [path, buf] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?;
99 let result = this.macos_fbsd_solarish_lstat(path, buf)?;
100 this.write_scalar(result, dest)?;
101 }
102 "fstat" | "fstat64" => {
103 let [fd, buf] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?;
104 let result = this.macos_fbsd_solarish_fstat(fd, buf)?;
105 this.write_scalar(result, dest)?;
106 }
107 "readdir" => {
108 let [dirp] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?;
109 let result = this.linux_solarish_readdir64("dirent", dirp)?;
110 this.write_scalar(result, dest)?;
111 }
112
113 "__xnet_socketpair" => {
115 let [domain, type_, protocol, sv] =
116 this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?;
117 let result = this.socketpair(domain, type_, protocol, sv)?;
118 this.write_scalar(result, dest)?;
119 }
120
121 "___errno" => {
123 let [] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?;
124 let errno_place = this.last_error_place()?;
125 this.write_scalar(errno_place.to_ref(this).to_scalar(), dest)?;
126 }
127
128 "stack_getbounds" => {
129 let [stack] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?;
130 let stack = this.deref_pointer_as(stack, this.libc_ty_layout("stack_t"))?;
131
132 this.write_int_fields_named(
133 &[
134 ("ss_sp", this.machine.stack_addr.into()),
135 ("ss_size", this.machine.stack_size.into()),
136 ("ss_flags", 0),
139 ],
140 &stack,
141 )?;
142
143 this.write_null(dest)?;
144 }
145
146 "pset_info" => {
147 let [pset, tpe, cpus, list] =
148 this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?;
149 let pset = this.read_scalar(pset)?.to_i32()?;
155 let tpe = this.read_pointer(tpe)?;
156 let list = this.read_pointer(list)?;
157
158 let ps_myid = this.eval_libc_i32("PS_MYID");
159 if ps_myid != pset {
160 throw_unsup_format!("pset_info is only supported with pset==PS_MYID");
161 }
162
163 if !this.ptr_is_null(tpe)? {
164 throw_unsup_format!("pset_info is only supported with type==NULL");
165 }
166
167 if !this.ptr_is_null(list)? {
168 throw_unsup_format!("pset_info is only supported with list==NULL");
169 }
170
171 let cpus = this.deref_pointer_as(cpus, this.machine.layouts.u32)?;
172 this.write_scalar(Scalar::from_u32(this.machine.num_cpus), &cpus)?;
173 this.write_null(dest)?;
174 }
175
176 "__sysconf_xpg7" => {
177 let [val] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?;
178 let result = this.sysconf(val)?;
179 this.write_scalar(result, dest)?;
180 }
181
182 _ => return interp_ok(EmulateItemResult::NotSupported),
183 }
184 interp_ok(EmulateItemResult::NeedsReturn)
185 }
186}