1use rustc_abi::CanonAbi;
2use rustc_middle::ty::Ty;
3use rustc_span::Symbol;
4use rustc_target::callconv::FnAbi;
5use rustc_target::spec::Os;
6
7use crate::shims::unix::foreign_items::EvalContextExt as _;
8use crate::shims::unix::linux_like::epoll::EvalContextExt as _;
9use crate::shims::unix::linux_like::eventfd::EvalContextExt as _;
10use crate::shims::unix::*;
11use crate::*;
12
13pub fn is_dyn_sym(name: &str) -> bool {
14 matches!(name, "pthread_setname_np")
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_create1" => {
30 this.assert_target_os(Os::Illumos, "epoll_create1");
31 let [flag] = this.check_shim_sig_deprecated(abi, CanonAbi::C, link_name, args)?;
32 let result = this.epoll_create1(flag)?;
33 this.write_scalar(result, dest)?;
34 }
35 "epoll_ctl" => {
36 this.assert_target_os(Os::Illumos, "epoll_ctl");
37 let [epfd, op, fd, event] =
38 this.check_shim_sig_deprecated(abi, CanonAbi::C, link_name, args)?;
39 let result = this.epoll_ctl(epfd, op, fd, event)?;
40 this.write_scalar(result, dest)?;
41 }
42 "epoll_wait" => {
43 this.assert_target_os(Os::Illumos, "epoll_wait");
44 let [epfd, events, maxevents, timeout] =
45 this.check_shim_sig_deprecated(abi, CanonAbi::C, link_name, args)?;
46 this.epoll_wait(epfd, events, maxevents, timeout, dest)?;
47 }
48 "eventfd" => {
49 this.assert_target_os(Os::Illumos, "eventfd");
50 let [val, flag] =
51 this.check_shim_sig_deprecated(abi, CanonAbi::C, link_name, args)?;
52 let result = this.eventfd(val, flag)?;
53 this.write_scalar(result, dest)?;
54 }
55
56 "pthread_setname_np" => {
58 let [thread, name] =
59 this.check_shim_sig_deprecated(abi, CanonAbi::C, link_name, args)?;
60 let max_len = 32;
63 let res = match this.pthread_setname_np(
65 this.read_scalar(thread)?,
66 this.read_scalar(name)?,
67 max_len,
68 false,
69 )? {
70 ThreadNameResult::Ok => Scalar::from_u32(0),
71 ThreadNameResult::NameTooLong => this.eval_libc("ERANGE"),
72 ThreadNameResult::ThreadNotFound => this.eval_libc("ESRCH"),
73 };
74 this.write_scalar(res, dest)?;
75 }
76 "pthread_getname_np" => {
77 let [thread, name, len] =
78 this.check_shim_sig_deprecated(abi, CanonAbi::C, link_name, args)?;
79 let res = match this.pthread_getname_np(
81 this.read_scalar(thread)?,
82 this.read_scalar(name)?,
83 this.read_scalar(len)?,
84 false,
85 )? {
86 ThreadNameResult::Ok => Scalar::from_u32(0),
87 ThreadNameResult::NameTooLong => this.eval_libc("ERANGE"),
88 ThreadNameResult::ThreadNotFound => this.eval_libc("ESRCH"),
89 };
90 this.write_scalar(res, dest)?;
91 }
92
93 "stat" => {
95 let [path, buf] =
97 this.check_shim_sig_deprecated(abi, CanonAbi::C, link_name, args)?;
98 let result = this.stat(path, buf)?;
99 this.write_scalar(result, dest)?;
100 }
101 "lstat" => {
102 let [path, buf] =
104 this.check_shim_sig_deprecated(abi, CanonAbi::C, link_name, args)?;
105 let result = this.lstat(path, buf)?;
106 this.write_scalar(result, dest)?;
107 }
108
109 "__xnet_socketpair" => {
111 let [domain, type_, protocol, sv] =
112 this.check_shim_sig_deprecated(abi, CanonAbi::C, link_name, args)?;
113 let result = this.socketpair(domain, type_, protocol, sv)?;
114 this.write_scalar(result, dest)?;
115 }
116
117 "__xnet_socket" | "__xnet7_socket" => {
119 let [domain, type_, protocol] = this.check_shim_sig(
120 shim_sig!(extern "C" fn(i32, i32, i32) -> i32),
121 (link_name, abi, args),
122 )?;
123 let result = this.socket(domain, type_, protocol)?;
124 this.write_scalar(result, dest)?;
125 }
126 "__xnet_bind" => {
127 let [socket, address, address_len] = this.check_shim_sig(
128 shim_sig!(extern "C" fn(i32, *_, libc::socklen_t) -> i32),
129 (link_name, abi, args),
130 )?;
131 let result = this.bind(socket, address, address_len)?;
132 this.write_scalar(result, dest)?;
133 }
134 "__xnet_connect" => {
135 let [socket, address, address_len] = this.check_shim_sig(
136 shim_sig!(extern "C" fn(i32, *_, libc::socklen_t) -> i32),
137 (link_name, abi, args),
138 )?;
139 this.connect(socket, address, address_len, dest)?;
140 }
141 "__xnet_getaddrinfo" => {
142 let [node, service, hints, res] = this.check_shim_sig(
143 shim_sig!(extern "C" fn(*_, *_, *_, *_) -> i32),
144 (link_name, abi, args),
145 )?;
146 let result = this.getaddrinfo(node, service, hints, res)?;
147 this.write_scalar(result, dest)?;
148 }
149 "__xnet_getsockopt" => {
150 let [socket, level, option_name, option_value, option_len] = this.check_shim_sig(
151 shim_sig!(extern "C" fn(i32, i32, i32, *_, *_) -> i32),
152 (link_name, abi, args),
153 )?;
154 let result =
155 this.getsockopt(socket, level, option_name, option_value, option_len)?;
156 this.write_scalar(result, dest)?;
157 }
158
159 "___errno" => {
161 let [] = this.check_shim_sig_deprecated(abi, CanonAbi::C, link_name, args)?;
162 let errno_place = this.last_error_place()?;
163 this.write_scalar(errno_place.to_ref(this).to_scalar(), dest)?;
164 }
165
166 "stack_getbounds" => {
167 let [stack] = this.check_shim_sig_deprecated(abi, CanonAbi::C, link_name, args)?;
169 let stack = this.deref_pointer_as(stack, this.libc_ty_layout("stack_t"))?;
170
171 this.write_int_fields_named(
172 &[
173 ("ss_sp", this.machine.stack_addr.into()),
174 ("ss_size", this.machine.stack_size.into()),
175 ("ss_flags", 0),
178 ],
179 &stack,
180 )?;
181
182 this.write_null(dest)?;
183 }
184
185 "pset_info" => {
186 let [pset, tpe, cpus, list] =
188 this.check_shim_sig_deprecated(abi, CanonAbi::C, link_name, args)?;
189 let pset = this.read_scalar(pset)?.to_i32()?;
195 let tpe = this.read_pointer(tpe)?;
196 let list = this.read_pointer(list)?;
197
198 let ps_myid = this.eval_libc_i32("PS_MYID");
199 if ps_myid != pset {
200 throw_unsup_format!("pset_info is only supported with pset==PS_MYID");
201 }
202
203 if !this.ptr_is_null(tpe)? {
204 throw_unsup_format!("pset_info is only supported with type==NULL");
205 }
206
207 if !this.ptr_is_null(list)? {
208 throw_unsup_format!("pset_info is only supported with list==NULL");
209 }
210
211 let cpus = this.deref_pointer_as(cpus, this.machine.layouts.u32)?;
212 this.write_scalar(Scalar::from_u32(this.machine.num_cpus), &cpus)?;
213 this.write_null(dest)?;
214 }
215
216 "__sysconf_xpg7" => {
217 let [val] = this.check_shim_sig_deprecated(abi, CanonAbi::C, link_name, args)?;
218 let result = this.sysconf(val)?;
219 this.write_scalar(result, dest)?;
220 }
221
222 _ => return interp_ok(EmulateItemResult::NotSupported),
223 }
224 interp_ok(EmulateItemResult::NeedsReturn)
225 }
226}