/*
- * Copyright (c) 1999-2007 Apple Inc. All rights reserved.
+ * Copyright (c) 1999-2016 Apple Inc. All rights reserved.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- *
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* unlawful or unlicensed copies of an Apple operating system, or to
* circumvent, violate, or enable the circumvention or violation of, any
* terms of an Apple operating system software license agreement.
- *
+ *
* Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this file.
- *
+ *
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
- *
+ *
* @APPLE_OSREFERENCE_LICENSE_HEADER_END@
*/
-/* Copyright 1998 Apple Computer, Inc. */
#include "SYS.h"
-#if defined(__ppc__) || defined(__ppc64__)
-
-/* This syscall is special cased: the timeval is returned in r3/r4.
- * Note also that the "seconds" field of the timeval is a long, so
- * it's size is mode dependent.
+/*
+ * A third argument, of type uint64_t*, was added to the gettimeofday syscall
+ * for use cases that also want to know the mach_absolute_time that matches the
+ * time value returned.
+ *
+ * __gettimeofday takes the traditional two arguments. It will zero out the
+ * third argument argument before entering the kernel, behaving like the old
+ * call.
+ *
+ * __gettimeofday_with_mach will pass it through and supporting kernels will
+ * copy-out the mach_absolute_time. Old kernels will leave the pointed to
+ * value alone.
*/
-MI_ENTRY_POINT(___gettimeofday)
- mr r12,r3 // save ptr to timeval
- SYSCALL_NONAME(gettimeofday,0)
- stg r3,0(r12) // "stw" in 32-bit mode, "std" in 64-bit mode
- stw r4,GPR_BYTES(r12)
- li r3,0
- blr
-#elif defined(__i386__)
+.private_extern ___gettimeofday_with_mach
+
+#if defined(__i386__)
-/*
- * This syscall is special cased: the timeval is returned in eax/edx.
- */
LABEL(___gettimeofday)
+ pushl $0
+ pushl 12(%esp)
+ pushl 12(%esp)
+ calll ___gettimeofday_with_mach
+ addl $12, %esp
+ ret
+
+LABEL(___gettimeofday_with_mach)
UNIX_SYSCALL_INT_NONAME(gettimeofday,0)
- mov 4(%esp),%ecx
- mov %eax,(%ecx)
- mov %edx,4(%ecx)
- xor %eax,%eax
- ret
+ /*
+ * <rdar://problem/26410029>
+ * If eax is 0, we're on a new kernel and timeval was written by the kernel.
+ * Otherwise, eax:edx contains the timeval and we marshal into timeval.
+ */
+ cmp $0, %eax
+ je 2f
+ mov 4(%esp),%ecx
+ mov %eax,(%ecx)
+ mov %edx,4(%ecx)
+ xor %eax,%eax
+2:
+ ret
#elif defined(__x86_64__)
-/*
- * This syscall is special cased: the timeval is returned in rax:rdx.
- */
+__SYSCALL(___gettimeofday_with_mach, gettimeofday, 3)
+
LABEL(___gettimeofday)
- UNIX_SYSCALL_NONAME(gettimeofday,0)
- movq %rax, (%rdi)
- movl %edx, 8(%rdi)
- xorl %eax, %eax
+ movq $0x0, %rdx // zero out third argument
+
+ UNIX_SYSCALL_NONAME(gettimeofday,0,cerror_nocancel)
+ /*
+ * <rdar://problem/26410029>
+ * If rax is 0, we're on a new kernel and timeval was written by the kernel.
+ * Otherwise, rax:rdx contains the timeval and we marshal into timeval.
+ */
+ cmp $0, %rax
+ je 2f
+ movq %rax, (%rdi)
+ movl %edx, 8(%rdi)
+ xorl %eax, %eax
+2:
ret
#else