Skip to content

Commit f430e54

Browse files
committed
implement mach_absolute_time for macOS
1 parent 04c937e commit f430e54

File tree

3 files changed

+27
-10
lines changed

3 files changed

+27
-10
lines changed

src/shims/foreign_items/posix/macos.rs

+4
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,10 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
6666
let result = this.gettimeofday(args[0], args[1])?;
6767
this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;
6868
}
69+
"mach_absolute_time" => {
70+
let result = this.mach_absolute_time()?;
71+
this.write_scalar(Scalar::from_uint(result, dest.layout.size), dest)?;
72+
}
6973

7074
// Other shims
7175
"pthread_attr_get_np" => {

src/shims/fs.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -574,8 +574,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
574574
buf_op: OpTy<'tcx, Tag>,
575575
) -> InterpResult<'tcx, i32> {
576576
let this = self.eval_context_mut();
577-
this.check_no_isolation("stat")?;
578577
this.assert_platform("macos", "stat");
578+
this.check_no_isolation("stat")?;
579579
// `stat` always follows symlinks.
580580
this.macos_stat_or_lstat(true, path_op, buf_op)
581581
}
@@ -587,8 +587,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
587587
buf_op: OpTy<'tcx, Tag>,
588588
) -> InterpResult<'tcx, i32> {
589589
let this = self.eval_context_mut();
590-
this.check_no_isolation("lstat")?;
591590
this.assert_platform("macos", "lstat");
591+
this.check_no_isolation("lstat")?;
592592
this.macos_stat_or_lstat(false, path_op, buf_op)
593593
}
594594

@@ -599,8 +599,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
599599
) -> InterpResult<'tcx, i32> {
600600
let this = self.eval_context_mut();
601601

602-
this.check_no_isolation("fstat")?;
603602
this.assert_platform("macos", "fstat");
603+
this.check_no_isolation("fstat")?;
604604

605605
let fd = this.read_scalar(fd_op)?.to_i32()?;
606606

@@ -621,8 +621,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
621621
) -> InterpResult<'tcx, i32> {
622622
let this = self.eval_context_mut();
623623

624-
this.check_no_isolation("statx")?;
625624
this.assert_platform("linux", "statx");
625+
this.check_no_isolation("statx")?;
626626

627627
let statxbuf_scalar = this.read_scalar(statxbuf_op)?.not_undef()?;
628628
let pathname_scalar = this.read_scalar(pathname_op)?.not_undef()?;
@@ -880,8 +880,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
880880
) -> InterpResult<'tcx, i32> {
881881
let this = self.eval_context_mut();
882882

883-
this.check_no_isolation("readdir64_r")?;
884883
this.assert_platform("linux", "readdir64_r");
884+
this.check_no_isolation("readdir64_r")?;
885885

886886
let dirp = this.read_scalar(dirp_op)?.to_machine_usize(this)?;
887887

@@ -967,8 +967,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
967967
) -> InterpResult<'tcx, i32> {
968968
let this = self.eval_context_mut();
969969

970-
this.check_no_isolation("readdir_r")?;
971970
this.assert_platform("macos", "readdir_r");
971+
this.check_no_isolation("readdir_r")?;
972972

973973
let dirp = this.read_scalar(dirp_op)?.to_machine_usize(this)?;
974974

src/shims/time.rs

+17-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use std::time::{Duration, SystemTime, Instant};
2+
use std::convert::TryFrom;
23

34
use crate::stacked_borrows::Tag;
45
use crate::*;
@@ -12,16 +13,15 @@ pub fn system_time_to_duration<'tcx>(time: &SystemTime) -> InterpResult<'tcx, Du
1213

1314
impl<'mir, 'tcx> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {}
1415
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> {
15-
// Foreign function used by linux
1616
fn clock_gettime(
1717
&mut self,
1818
clk_id_op: OpTy<'tcx, Tag>,
1919
tp_op: OpTy<'tcx, Tag>,
2020
) -> InterpResult<'tcx, i32> {
2121
let this = self.eval_context_mut();
2222

23+
this.assert_platform("linux", "clock_gettime");
2324
this.check_no_isolation("clock_gettime")?;
24-
this.assert_platform("linux");
2525

2626
let clk_id = this.read_scalar(clk_id_op)?.to_i32()?;
2727
let tp = this.deref_operand(tp_op)?;
@@ -50,16 +50,16 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
5050

5151
Ok(0)
5252
}
53-
// Foreign function used by generic unix (in particular macOS)
53+
5454
fn gettimeofday(
5555
&mut self,
5656
tv_op: OpTy<'tcx, Tag>,
5757
tz_op: OpTy<'tcx, Tag>,
5858
) -> InterpResult<'tcx, i32> {
5959
let this = self.eval_context_mut();
6060

61+
this.assert_platform("macos", "gettimeofday");
6162
this.check_no_isolation("gettimeofday")?;
62-
this.assert_platform("macos");
6363

6464
// Using tz is obsolete and should always be null
6565
let tz = this.read_scalar(tz_op)?.not_undef()?;
@@ -84,4 +84,17 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
8484

8585
Ok(0)
8686
}
87+
88+
fn mach_absolute_time(&self) -> InterpResult<'tcx, u64> {
89+
let this = self.eval_context_ref();
90+
91+
this.assert_platform("macos", "mach_absolute_time");
92+
this.check_no_isolation("mach_absolute_time")?;
93+
94+
// This returns a u64, with time units determined dynamically by `mach_timebase_info`.
95+
// We return plain nanoseconds.
96+
let duration = Instant::now().duration_since(this.machine.time_anchor);
97+
u64::try_from(duration.as_nanos())
98+
.map_err(|_| err_unsup_format!("programs running longer than 2^64 nanoseconds are not supported").into())
99+
}
87100
}

0 commit comments

Comments
 (0)