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(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] = this.check_shim(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 this.assert_target_os("illumos", "epoll_wait");
42 let [epfd, events, maxevents, timeout] =
43 this.check_shim(abi, CanonAbi::C, link_name, args)?;
44 this.epoll_wait(epfd, events, maxevents, timeout, dest)?;
45 }
46 "eventfd" => {
47 this.assert_target_os("illumos", "eventfd");
48 let [val, flag] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
49 let result = this.eventfd(val, flag)?;
50 this.write_scalar(result, dest)?;
51 }
52
53 "pthread_setname_np" => {
55 let [thread, name] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
56 let max_len = 32;
59 let res = match this.pthread_setname_np(
61 this.read_scalar(thread)?,
62 this.read_scalar(name)?,
63 max_len,
64 false,
65 )? {
66 ThreadNameResult::Ok => Scalar::from_u32(0),
67 ThreadNameResult::NameTooLong => this.eval_libc("ERANGE"),
68 ThreadNameResult::ThreadNotFound => this.eval_libc("ESRCH"),
69 };
70 this.write_scalar(res, dest)?;
71 }
72 "pthread_getname_np" => {
73 let [thread, name, len] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
74 let res = match this.pthread_getname_np(
76 this.read_scalar(thread)?,
77 this.read_scalar(name)?,
78 this.read_scalar(len)?,
79 false,
80 )? {
81 ThreadNameResult::Ok => Scalar::from_u32(0),
82 ThreadNameResult::NameTooLong => this.eval_libc("ERANGE"),
83 ThreadNameResult::ThreadNotFound => this.eval_libc("ESRCH"),
84 };
85 this.write_scalar(res, dest)?;
86 }
87
88 "stat" | "stat64" => {
90 let [path, buf] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
91 let result = this.macos_fbsd_solarish_stat(path, buf)?;
92 this.write_scalar(result, dest)?;
93 }
94 "lstat" | "lstat64" => {
95 let [path, buf] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
96 let result = this.macos_fbsd_solarish_lstat(path, buf)?;
97 this.write_scalar(result, dest)?;
98 }
99 "fstat" | "fstat64" => {
100 let [fd, buf] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
101 let result = this.macos_fbsd_solarish_fstat(fd, buf)?;
102 this.write_scalar(result, dest)?;
103 }
104 "readdir" => {
105 let [dirp] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
106 let result = this.linux_solarish_readdir64("dirent", dirp)?;
107 this.write_scalar(result, dest)?;
108 }
109
110 "__xnet_socketpair" => {
112 let [domain, type_, protocol, sv] =
113 this.check_shim(abi, CanonAbi::C, link_name, args)?;
114 let result = this.socketpair(domain, type_, protocol, sv)?;
115 this.write_scalar(result, dest)?;
116 }
117
118 "___errno" => {
120 let [] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
121 let errno_place = this.last_error_place()?;
122 this.write_scalar(errno_place.to_ref(this).to_scalar(), dest)?;
123 }
124
125 "stack_getbounds" => {
126 let [stack] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
127 let stack = this.deref_pointer_as(stack, this.libc_ty_layout("stack_t"))?;
128
129 this.write_int_fields_named(
130 &[
131 ("ss_sp", this.machine.stack_addr.into()),
132 ("ss_size", this.machine.stack_size.into()),
133 ("ss_flags", 0),
136 ],
137 &stack,
138 )?;
139
140 this.write_null(dest)?;
141 }
142
143 "pset_info" => {
144 let [pset, tpe, cpus, list] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
145 let pset = this.read_scalar(pset)?.to_i32()?;
151 let tpe = this.read_pointer(tpe)?;
152 let list = this.read_pointer(list)?;
153
154 let ps_myid = this.eval_libc_i32("PS_MYID");
155 if ps_myid != pset {
156 throw_unsup_format!("pset_info is only supported with pset==PS_MYID");
157 }
158
159 if !this.ptr_is_null(tpe)? {
160 throw_unsup_format!("pset_info is only supported with type==NULL");
161 }
162
163 if !this.ptr_is_null(list)? {
164 throw_unsup_format!("pset_info is only supported with list==NULL");
165 }
166
167 let cpus = this.deref_pointer_as(cpus, this.machine.layouts.u32)?;
168 this.write_scalar(Scalar::from_u32(this.machine.num_cpus), &cpus)?;
169 this.write_null(dest)?;
170 }
171
172 "__sysconf_xpg7" => {
173 let [val] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
174 let result = this.sysconf(val)?;
175 this.write_scalar(result, dest)?;
176 }
177
178 _ => return interp_ok(EmulateItemResult::NotSupported),
179 }
180 interp_ok(EmulateItemResult::NeedsReturn)
181 }
182}