]> git.lizzy.rs Git - rust.git/blob - src/shims/unix/macos/foreign_items.rs
some clippy-induced cleanup
[rust.git] / src / shims / unix / macos / foreign_items.rs
1 use rustc_middle::mir;
2 use rustc_span::Symbol;
3 use rustc_target::spec::abi::Abi;
4
5 use crate::*;
6 use shims::foreign_items::EmulateByNameResult;
7 use shims::unix::fs::EvalContextExt as _;
8 use shims::unix::thread::EvalContextExt as _;
9
10 impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {}
11 pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> {
12     fn emulate_foreign_item_by_name(
13         &mut self,
14         link_name: Symbol,
15         abi: Abi,
16         args: &[OpTy<'tcx, Tag>],
17         dest: &PlaceTy<'tcx, Tag>,
18         _ret: mir::BasicBlock,
19     ) -> InterpResult<'tcx, EmulateByNameResult<'mir, 'tcx>> {
20         let this = self.eval_context_mut();
21
22         match link_name.as_str() {
23             // errno
24             "__error" => {
25                 let [] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
26                 let errno_place = this.last_error_place()?;
27                 this.write_scalar(errno_place.to_ref(this).to_scalar()?, dest)?;
28             }
29
30             // File related shims
31             "close" | "close$NOCANCEL" => {
32                 let [result] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
33                 let result = this.close(result)?;
34                 this.write_scalar(Scalar::from_i32(result), dest)?;
35             }
36             "stat" | "stat$INODE64" => {
37                 let [path, buf] =
38                     this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
39                 let result = this.macos_stat(path, buf)?;
40                 this.write_scalar(Scalar::from_i32(result), dest)?;
41             }
42             "lstat" | "lstat$INODE64" => {
43                 let [path, buf] =
44                     this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
45                 let result = this.macos_lstat(path, buf)?;
46                 this.write_scalar(Scalar::from_i32(result), dest)?;
47             }
48             "fstat" | "fstat$INODE64" => {
49                 let [fd, buf] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
50                 let result = this.macos_fstat(fd, buf)?;
51                 this.write_scalar(Scalar::from_i32(result), dest)?;
52             }
53             "opendir" | "opendir$INODE64" => {
54                 let [name] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
55                 let result = this.opendir(name)?;
56                 this.write_scalar(result, dest)?;
57             }
58             "readdir_r" | "readdir_r$INODE64" => {
59                 let [dirp, entry, result] =
60                     this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
61                 let result = this.macos_readdir_r(dirp, entry, result)?;
62                 this.write_scalar(Scalar::from_i32(result), dest)?;
63             }
64             "ftruncate" => {
65                 let [fd, length] =
66                     this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
67                 let result = this.ftruncate64(fd, length)?;
68                 this.write_scalar(Scalar::from_i32(result), dest)?;
69             }
70
71             // Environment related shims
72             "_NSGetEnviron" => {
73                 let [] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
74                 this.write_pointer(
75                     this.machine.env_vars.environ.expect("machine must be initialized").ptr,
76                     dest,
77                 )?;
78             }
79
80             // Time related shims
81             "gettimeofday" => {
82                 let [tv, tz] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
83                 let result = this.gettimeofday(tv, tz)?;
84                 this.write_scalar(Scalar::from_i32(result), dest)?;
85             }
86             "mach_absolute_time" => {
87                 let [] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
88                 let result = this.mach_absolute_time()?;
89                 this.write_scalar(Scalar::from_u64(result), dest)?;
90             }
91
92             "mach_timebase_info" => {
93                 let [info] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
94                 let result = this.mach_timebase_info(info)?;
95                 this.write_scalar(Scalar::from_i32(result), dest)?;
96             }
97
98             // Access to command-line arguments
99             "_NSGetArgc" => {
100                 let [] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
101                 this.write_pointer(
102                     this.machine.argc.expect("machine must be initialized").ptr,
103                     dest,
104                 )?;
105             }
106             "_NSGetArgv" => {
107                 let [] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
108                 this.write_pointer(
109                     this.machine.argv.expect("machine must be initialized").ptr,
110                     dest,
111                 )?;
112             }
113
114             // Thread-local storage
115             "_tlv_atexit" => {
116                 let [dtor, data] =
117                     this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
118                 let dtor = this.read_pointer(dtor)?;
119                 let dtor = this.get_ptr_fn(dtor)?.as_instance()?;
120                 let data = this.read_scalar(data)?.check_init()?;
121                 let active_thread = this.get_active_thread();
122                 this.machine.tls.set_macos_thread_dtor(active_thread, dtor, data)?;
123             }
124
125             // Querying system information
126             "pthread_get_stackaddr_np" => {
127                 let [thread] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
128                 this.read_scalar(thread)?.to_machine_usize(this)?;
129                 let stack_addr = Scalar::from_uint(STACK_ADDR, this.pointer_size());
130                 this.write_scalar(stack_addr, dest)?;
131             }
132             "pthread_get_stacksize_np" => {
133                 let [thread] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
134                 this.read_scalar(thread)?.to_machine_usize(this)?;
135                 let stack_size = Scalar::from_uint(STACK_SIZE, this.pointer_size());
136                 this.write_scalar(stack_size, dest)?;
137             }
138
139             // Threading
140             "pthread_setname_np" => {
141                 let [name] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
142                 let name = this.read_pointer(name)?;
143                 this.pthread_setname_np(name)?;
144             }
145
146             // Incomplete shims that we "stub out" just to get pre-main initialization code to work.
147             // These shims are enabled only when the caller is in the standard library.
148             "mmap" if this.frame_in_std() => {
149                 // This is a horrible hack, but since the guard page mechanism calls mmap and expects a particular return value, we just give it that value.
150                 let [addr, _, _, _, _, _] =
151                     this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
152                 let addr = this.read_scalar(addr)?.check_init()?;
153                 this.write_scalar(addr, dest)?;
154             }
155
156             _ => return Ok(EmulateByNameResult::NotSupported),
157         };
158
159         Ok(EmulateByNameResult::NeedsJumping)
160     }
161 }