1 use crate::stacked_borrows::Tag;
4 use std::time::{Duration, SystemTime};
6 fn get_time() -> (Duration, i128) {
8 let duration = SystemTime::now()
9 .duration_since(SystemTime::UNIX_EPOCH)
17 impl<'mir, 'tcx> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {}
18 pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> {
19 // Foreign function used by linux
22 clk_id_op: OpTy<'tcx, Tag>,
23 tp_op: OpTy<'tcx, Tag>,
24 ) -> InterpResult<'tcx, i32> {
25 let this = self.eval_context_mut();
27 if !this.machine.communicate {
28 throw_unsup_format!("`clock_gettime` not available when isolation is enabled")
31 let clk_id = this.read_scalar(clk_id_op)?.to_i32()?;
32 if clk_id != this.eval_libc_i32("CLOCK_REALTIME")? {
33 let einval = this.eval_libc("EINVAL")?;
34 this.set_last_error(einval)?;
38 let tp = this.force_ptr(this.read_scalar(tp_op)?.not_undef()?)?;
40 let (duration, sign) = get_time();
41 let tv_sec = sign * (duration.as_secs() as i128);
42 let mut tv_nsec = duration.subsec_nanos() as i128;
43 // If the number of seconds is zero, we need to put the sign into the second's fraction.
44 if tv_sec == 0 && sign < 0 {
48 this.write_c_ints(&tp, &[tv_sec, tv_nsec], &["time_t", "c_long"])?;
52 // Foreign function used by generic unix
55 tv_op: OpTy<'tcx, Tag>,
56 tz_op: OpTy<'tcx, Tag>,
57 ) -> InterpResult<'tcx, i32> {
58 let this = self.eval_context_mut();
60 if !this.machine.communicate {
61 throw_unsup_format!("`gettimeofday` not available when isolation is enabled")
63 // Using tz is obsolete and should always be null
64 let tz = this.read_scalar(tz_op)?.not_undef()?;
65 if !this.is_null(tz)? {
66 let einval = this.eval_libc("EINVAL")?;
67 this.set_last_error(einval)?;
71 let tv = this.force_ptr(this.read_scalar(tv_op)?.not_undef()?)?;
73 let (duration, sign) = get_time();
74 let tv_sec = sign * (duration.as_secs() as i128);
75 let mut tv_usec = duration.subsec_micros() as i128;
76 // If the number of seconds is zero, we need to put the sign into the second's fraction.
77 if tv_sec == 0 && sign < 0 {
81 this.write_c_ints(&tv, &[tv_sec, tv_usec], &["time_t", "suseconds_t"])?;