@@ -21,16 +21,18 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
21
21
& mut self ,
22
22
clk_id_op : & OpTy < ' tcx > ,
23
23
tp_op : & OpTy < ' tcx > ,
24
- ) -> InterpResult < ' tcx , Scalar > {
24
+ dest : & MPlaceTy < ' tcx > ,
25
+ ) -> InterpResult < ' tcx > {
25
26
// This clock support is deliberately minimal because a lot of clock types have fiddly
26
27
// properties (is it possible for Miri to be suspended independently of the host?). If you
27
28
// have a use for another clock type, please open an issue.
28
29
29
30
let this = self . eval_context_mut ( ) ;
30
31
31
32
this. assert_target_os_is_unix ( "clock_gettime" ) ;
33
+ let clockid_t_size = this. libc_ty_layout ( "clockid_t" ) . size ;
32
34
33
- let clk_id = this. read_scalar ( clk_id_op) ?. to_i32 ( ) ?;
35
+ let clk_id = this. read_scalar ( clk_id_op) ?. to_int ( clockid_t_size ) ?;
34
36
let tp = this. deref_pointer_as ( tp_op, this. libc_ty_layout ( "timespec" ) ) ?;
35
37
36
38
let absolute_clocks;
@@ -43,34 +45,34 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
43
45
// Linux further distinguishes regular and "coarse" clocks, but the "coarse" version
44
46
// is just specified to be "faster and less precise", so we implement both the same way.
45
47
absolute_clocks = vec ! [
46
- this. eval_libc_i32 ( "CLOCK_REALTIME" ) ,
47
- this. eval_libc_i32 ( "CLOCK_REALTIME_COARSE" ) ,
48
+ this. eval_libc ( "CLOCK_REALTIME" ) . to_int ( clockid_t_size ) ? ,
49
+ this. eval_libc ( "CLOCK_REALTIME_COARSE" ) . to_int ( clockid_t_size ) ? ,
48
50
] ;
49
51
// The second kind is MONOTONIC clocks for which 0 is an arbitrary time point, but they are
50
52
// never allowed to go backwards. We don't need to do any additional monotonicity
51
53
// enforcement because std::time::Instant already guarantees that it is monotonic.
52
54
relative_clocks = vec ! [
53
- this. eval_libc_i32 ( "CLOCK_MONOTONIC" ) ,
54
- this. eval_libc_i32 ( "CLOCK_MONOTONIC_COARSE" ) ,
55
+ this. eval_libc ( "CLOCK_MONOTONIC" ) . to_int ( clockid_t_size ) ? ,
56
+ this. eval_libc ( "CLOCK_MONOTONIC_COARSE" ) . to_int ( clockid_t_size ) ? ,
55
57
] ;
56
58
}
57
59
"macos" => {
58
- absolute_clocks = vec ! [ this. eval_libc_i32 ( "CLOCK_REALTIME" ) ] ;
59
- relative_clocks = vec ! [ this. eval_libc_i32 ( "CLOCK_MONOTONIC" ) ] ;
60
+ absolute_clocks = vec ! [ this. eval_libc ( "CLOCK_REALTIME" ) . to_int ( clockid_t_size ) ? ] ;
61
+ relative_clocks = vec ! [ this. eval_libc ( "CLOCK_MONOTONIC" ) . to_int ( clockid_t_size ) ? ] ;
60
62
// `CLOCK_UPTIME_RAW` supposed to not increment while the system is asleep... but
61
63
// that's not really something a program running inside Miri can tell, anyway.
62
64
// We need to support it because std uses it.
63
- relative_clocks. push ( this. eval_libc_i32 ( "CLOCK_UPTIME_RAW" ) ) ;
65
+ relative_clocks. push ( this. eval_libc ( "CLOCK_UPTIME_RAW" ) . to_int ( clockid_t_size ) ? ) ;
64
66
}
65
67
"solaris" | "illumos" => {
66
68
// The REALTIME clock returns the actual time since the Unix epoch.
67
- absolute_clocks = vec ! [ this. eval_libc_i32 ( "CLOCK_REALTIME" ) ] ;
69
+ absolute_clocks = vec ! [ this. eval_libc ( "CLOCK_REALTIME" ) . to_int ( clockid_t_size ) ? ] ;
68
70
// MONOTONIC, in the other hand, is the high resolution, non-adjustable
69
71
// clock from an arbitrary time in the past.
70
72
// Note that the man page mentions HIGHRES but it is just
71
73
// an alias of MONOTONIC and the libc crate does not expose it anyway.
72
74
// https://docs.oracle.com/cd/E23824_01/html/821-1465/clock-gettime-3c.html
73
- relative_clocks = vec ! [ this. eval_libc_i32 ( "CLOCK_MONOTONIC" ) ] ;
75
+ relative_clocks = vec ! [ this. eval_libc ( "CLOCK_MONOTONIC" ) . to_int ( clockid_t_size ) ? ] ;
74
76
}
75
77
target => throw_unsup_format ! ( "`clock_gettime` is not supported on target OS {target}" ) ,
76
78
}
@@ -81,15 +83,16 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
81
83
} else if relative_clocks. contains ( & clk_id) {
82
84
this. machine . monotonic_clock . now ( ) . duration_since ( this. machine . monotonic_clock . epoch ( ) )
83
85
} else {
84
- return this. set_last_error_and_return_i32 ( LibcError ( "EINVAL" ) ) ;
86
+ return this. set_last_error_and_return ( LibcError ( "EINVAL" ) , dest ) ;
85
87
} ;
86
88
87
89
let tv_sec = duration. as_secs ( ) ;
88
90
let tv_nsec = duration. subsec_nanos ( ) ;
89
91
90
92
this. write_int_fields ( & [ tv_sec. into ( ) , tv_nsec. into ( ) ] , & tp) ?;
93
+ this. write_int ( 0 , dest) ?;
91
94
92
- interp_ok ( Scalar :: from_i32 ( 0 ) )
95
+ interp_ok ( ( ) )
93
96
}
94
97
95
98
fn gettimeofday (
0 commit comments