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