miri/shims/unix/solarish/
foreign_items.rs1use 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_lenient(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_lenient(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_lenient(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] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?;
51 let result = this.eventfd(val, flag)?;
52 this.write_scalar(result, dest)?;
53 }
54
55 "pthread_setname_np" => {
57 let [thread, name] =
58 this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?;
59 let max_len = 32;
62 let res = match this.pthread_setname_np(
64 this.read_scalar(thread)?,
65 this.read_scalar(name)?,
66 max_len,
67 false,
68 )? {
69 ThreadNameResult::Ok => Scalar::from_u32(0),
70 ThreadNameResult::NameTooLong => this.eval_libc("ERANGE"),
71 ThreadNameResult::ThreadNotFound => this.eval_libc("ESRCH"),
72 };
73 this.write_scalar(res, dest)?;
74 }
75 "pthread_getname_np" => {
76 let [thread, name, len] =
77 this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?;
78 let res = match this.pthread_getname_np(
80 this.read_scalar(thread)?,
81 this.read_scalar(name)?,
82 this.read_scalar(len)?,
83 false,
84 )? {
85 ThreadNameResult::Ok => Scalar::from_u32(0),
86 ThreadNameResult::NameTooLong => this.eval_libc("ERANGE"),
87 ThreadNameResult::ThreadNotFound => this.eval_libc("ESRCH"),
88 };
89 this.write_scalar(res, dest)?;
90 }
91
92 "stat" | "stat64" => {
94 let [path, buf] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?;
95 let result = this.macos_fbsd_solarish_stat(path, buf)?;
96 this.write_scalar(result, dest)?;
97 }
98 "lstat" | "lstat64" => {
99 let [path, buf] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?;
100 let result = this.macos_fbsd_solarish_lstat(path, buf)?;
101 this.write_scalar(result, dest)?;
102 }
103 "fstat" | "fstat64" => {
104 let [fd, buf] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?;
105 let result = this.macos_fbsd_solarish_fstat(fd, buf)?;
106 this.write_scalar(result, dest)?;
107 }
108 "readdir" => {
109 let [dirp] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?;
110 let result = this.readdir64("dirent", dirp)?;
111 this.write_scalar(result, dest)?;
112 }
113
114 "__xnet_socketpair" => {
116 let [domain, type_, protocol, sv] =
117 this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?;
118 let result = this.socketpair(domain, type_, protocol, sv)?;
119 this.write_scalar(result, dest)?;
120 }
121
122 "___errno" => {
124 let [] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?;
125 let errno_place = this.last_error_place()?;
126 this.write_scalar(errno_place.to_ref(this).to_scalar(), dest)?;
127 }
128
129 "stack_getbounds" => {
130 let [stack] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?;
131 let stack = this.deref_pointer_as(stack, this.libc_ty_layout("stack_t"))?;
132
133 this.write_int_fields_named(
134 &[
135 ("ss_sp", this.machine.stack_addr.into()),
136 ("ss_size", this.machine.stack_size.into()),
137 ("ss_flags", 0),
140 ],
141 &stack,
142 )?;
143
144 this.write_null(dest)?;
145 }
146
147 "pset_info" => {
148 let [pset, tpe, cpus, list] =
149 this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?;
150 let pset = this.read_scalar(pset)?.to_i32()?;
156 let tpe = this.read_pointer(tpe)?;
157 let list = this.read_pointer(list)?;
158
159 let ps_myid = this.eval_libc_i32("PS_MYID");
160 if ps_myid != pset {
161 throw_unsup_format!("pset_info is only supported with pset==PS_MYID");
162 }
163
164 if !this.ptr_is_null(tpe)? {
165 throw_unsup_format!("pset_info is only supported with type==NULL");
166 }
167
168 if !this.ptr_is_null(list)? {
169 throw_unsup_format!("pset_info is only supported with list==NULL");
170 }
171
172 let cpus = this.deref_pointer_as(cpus, this.machine.layouts.u32)?;
173 this.write_scalar(Scalar::from_u32(this.machine.num_cpus), &cpus)?;
174 this.write_null(dest)?;
175 }
176
177 "__sysconf_xpg7" => {
178 let [val] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?;
179 let result = this.sysconf(val)?;
180 this.write_scalar(result, dest)?;
181 }
182
183 _ => return interp_ok(EmulateItemResult::NotSupported),
184 }
185 interp_ok(EmulateItemResult::NeedsReturn)
186 }
187}