Auto merge of #2286 - LegNeato:patch-2, r=RalfJung

Support `gettimeofday` on more than macos

This appears to be in linux and in openbsd as well:

* https://github.com/torvalds/linux/blob/master/lib/vdso/gettimeofday.c
* https://github.com/openbsd/src/blob/master/sys/sys/time.h#L439

Note that std currently says [different syscalls are used on mac vs linux](https://doc.rust-lang.org/std/time/struct.SystemTime.html#platform-specific-behavior) but this is not part of[ std's contract](https://doc.rust-lang.org/std/io/index.html#platform-specific-behavior) and third party code could call the syscall directly on different platforms.
This commit is contained in:
bors 2022-06-29 22:39:57 +00:00
commit 1b3332a0a6
4 changed files with 30 additions and 6 deletions

View File

@ -64,7 +64,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
) -> InterpResult<'tcx, i32> {
let this = self.eval_context_mut();
this.assert_target_os("macos", "gettimeofday");
this.assert_target_os_is_unix("gettimeofday");
this.check_no_isolation("`gettimeofday`")?;
// Using tz is obsolete and should always be null

View File

@ -139,6 +139,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
this.write_scalar(Scalar::from_machine_isize(result, this), dest)?;
}
// Time related shims
"gettimeofday" => {
let [tv, tz] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
let result = this.gettimeofday(tv, tz)?;
this.write_scalar(Scalar::from_i32(result), dest)?;
}
// Allocation
"posix_memalign" => {
let [ret, align, size] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;

View File

@ -78,11 +78,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
}
// Time related shims
"gettimeofday" => {
let [tv, tz] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
let result = this.gettimeofday(tv, tz)?;
this.write_scalar(Scalar::from_i32(result), dest)?;
}
"mach_absolute_time" => {
let [] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
let result = this.mach_absolute_time()?;

View File

@ -290,10 +290,32 @@ fn test_clocks() {
assert_eq!(is_error, 0);
}
fn test_posix_gettimeofday() {
let mut tp = std::mem::MaybeUninit::<libc::timeval>::uninit();
let tz = std::ptr::null_mut::<libc::timezone>();
#[cfg(target_os = "macos")] // `tz` has a different type on macOS
let tz = tz as *mut libc::c_void;
let is_error = unsafe { libc::gettimeofday(tp.as_mut_ptr(), tz) };
assert_eq!(is_error, 0);
let tv = unsafe { tp.assume_init() };
assert!(tv.tv_sec > 0);
assert!(tv.tv_usec >= 0); // Theoretically this could be 0.
// Test that non-null tz returns an error.
let mut tz = std::mem::MaybeUninit::<libc::timezone>::uninit();
let tz_ptr = tz.as_mut_ptr();
#[cfg(target_os = "macos")] // `tz` has a different type on macOS
let tz_ptr = tz_ptr as *mut libc::c_void;
let is_error = unsafe { libc::gettimeofday(tp.as_mut_ptr(), tz_ptr) };
assert_eq!(is_error, -1);
}
fn main() {
#[cfg(any(target_os = "linux", target_os = "freebsd"))]
test_posix_fadvise();
test_posix_gettimeofday();
#[cfg(any(target_os = "linux", target_os = "freebsd"))]
test_sync_file_range();