1use rustc_abi::CanonAbi;
2use rustc_middle::ty::Ty;
3use rustc_span::Symbol;
4use rustc_target::callconv::FnAbi;
5
6use super::sync::EvalContextExt as _;
7use crate::shims::unix::*;
8use crate::*;
9
10pub fn is_dyn_sym(_name: &str) -> bool {
11 false
12}
13
14impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
15pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
16 fn emulate_foreign_item_inner(
17 &mut self,
18 link_name: Symbol,
19 abi: &FnAbi<'tcx, Ty<'tcx>>,
20 args: &[OpTy<'tcx>],
21 dest: &MPlaceTy<'tcx>,
22 ) -> InterpResult<'tcx, EmulateItemResult> {
23 let this = self.eval_context_mut();
24 match link_name.as_str() {
25 "pthread_setname_np" => {
27 let [thread, name] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
28 let max_len = u64::MAX; let res = match this.pthread_setname_np(
30 this.read_scalar(thread)?,
31 this.read_scalar(name)?,
32 max_len,
33 false,
34 )? {
35 ThreadNameResult::Ok => Scalar::from_u32(0),
36 ThreadNameResult::NameTooLong => unreachable!(),
37 ThreadNameResult::ThreadNotFound => this.eval_libc("ESRCH"),
38 };
39 this.write_scalar(res, dest)?;
40 }
41 "pthread_getname_np" => {
42 let [thread, name, len] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
43 let res = match this.pthread_getname_np(
47 this.read_scalar(thread)?,
48 this.read_scalar(name)?,
49 this.read_scalar(len)?,
50 true,
51 )? {
52 ThreadNameResult::Ok => Scalar::from_u32(0),
53 ThreadNameResult::NameTooLong => Scalar::from_u32(0),
55 ThreadNameResult::ThreadNotFound => this.eval_libc("ESRCH"),
56 };
57 this.write_scalar(res, dest)?;
58 }
59
60 "cpuset_getaffinity" => {
61 let [level, which, id, set_size, mask] =
63 this.check_shim(abi, CanonAbi::C, link_name, args)?;
64
65 let level = this.read_scalar(level)?.to_i32()?;
66 let which = this.read_scalar(which)?.to_i32()?;
67 let id = this.read_scalar(id)?.to_i64()?;
68 let set_size = this.read_target_usize(set_size)?; let mask = this.read_pointer(mask)?;
70
71 let _level_root = this.eval_libc_i32("CPU_LEVEL_ROOT");
72 let _level_cpuset = this.eval_libc_i32("CPU_LEVEL_CPUSET");
73 let level_which = this.eval_libc_i32("CPU_LEVEL_WHICH");
74
75 let _which_tid = this.eval_libc_i32("CPU_WHICH_TID");
76 let which_pid = this.eval_libc_i32("CPU_WHICH_PID");
77 let _which_jail = this.eval_libc_i32("CPU_WHICH_JAIL");
78 let _which_cpuset = this.eval_libc_i32("CPU_WHICH_CPUSET");
79 let _which_irq = this.eval_libc_i32("CPU_WHICH_IRQ");
80
81 let id = match id {
84 -1 => this.active_thread(),
85 _ =>
86 throw_unsup_format!(
87 "`cpuset_getaffinity` is only supported with a pid of -1 (indicating the current thread)"
88 ),
89 };
90
91 if this.ptr_is_null(mask)? {
92 this.set_last_error_and_return(LibcError("EFAULT"), dest)?;
93 }
94 else if level != level_which || which != which_pid {
97 throw_unsup_format!(
98 "`cpuset_getaffinity` is only supported with `level` set to CPU_LEVEL_WHICH and `which` set to CPU_WHICH_PID."
99 );
100 } else if let Some(cpuset) = this.machine.thread_cpu_affinity.get(&id) {
101 if set_size < u64::from(this.machine.num_cpus).div_ceil(8) {
107 this.set_last_error_and_return(LibcError("ERANGE"), dest)?;
108 } else {
109 let cpuset = cpuset.clone();
110 let byte_count =
111 Ord::min(cpuset.as_slice().len(), set_size.try_into().unwrap());
112 this.write_bytes_ptr(
113 mask,
114 cpuset.as_slice()[..byte_count].iter().copied(),
115 )?;
116 this.write_null(dest)?;
117 }
118 } else {
119 unreachable!();
121 }
122 }
123
124 "_umtx_op" => {
126 let [obj, op, val, uaddr, uaddr2] =
127 this.check_shim(abi, CanonAbi::C, link_name, args)?;
128 this._umtx_op(obj, op, val, uaddr, uaddr2, dest)?;
129 }
130
131 "stat" | "stat@FBSD_1.0" => {
135 let [path, buf] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
136 let result = this.macos_fbsd_solarish_stat(path, buf)?;
137 this.write_scalar(result, dest)?;
138 }
139 "lstat" | "lstat@FBSD_1.0" => {
140 let [path, buf] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
141 let result = this.macos_fbsd_solarish_lstat(path, buf)?;
142 this.write_scalar(result, dest)?;
143 }
144 "fstat" | "fstat@FBSD_1.0" => {
145 let [fd, buf] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
146 let result = this.macos_fbsd_solarish_fstat(fd, buf)?;
147 this.write_scalar(result, dest)?;
148 }
149 "readdir_r" | "readdir_r@FBSD_1.0" => {
150 let [dirp, entry, result] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
151 let result = this.macos_fbsd_readdir_r(dirp, entry, result)?;
152 this.write_scalar(result, dest)?;
153 }
154
155 "__error" => {
157 let [] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
158 let errno_place = this.last_error_place()?;
159 this.write_scalar(errno_place.to_ref(this).to_scalar(), dest)?;
160 }
161
162 "pthread_attr_get_np" if this.frame_in_std() => {
165 let [_thread, _attr] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
166 this.write_null(dest)?;
167 }
168
169 _ => return interp_ok(EmulateItemResult::NotSupported),
170 }
171 interp_ok(EmulateItemResult::NeedsReturn)
172 }
173}