aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShenghou Ma <minux@golang.org>2016-08-04 21:34:06 -0400
committerMinux Ma <minux@golang.org>2016-08-05 20:47:34 +0000
commit9fde86b0124b8c75000eb5d05887eff922a24566 (patch)
treec59a36760e14ae00e3ffe8181c0aa03263d2d557
parent3a03e877cc03c1fd155055e60a3f1f9cb8bda8d0 (diff)
downloadgo-9fde86b0124b8c75000eb5d05887eff922a24566.tar.gz
go-9fde86b0124b8c75000eb5d05887eff922a24566.zip
runtime, syscall: fix kernel gettimeofday ABI change on iOS 10
Fixes #16570 on iOS. Thanks Daniel Burhans for reporting the bug and testing the fix. Change-Id: I43ae7b78c8f85a131ed3d93ea59da9f32a02cd8f Reviewed-on: https://go-review.googlesource.com/25481 Reviewed-by: Ian Lance Taylor <iant@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
-rw-r--r--src/runtime/sys_darwin_arm.s15
-rw-r--r--src/runtime/sys_darwin_arm64.s14
-rw-r--r--src/syscall/syscall_darwin_arm.go13
-rw-r--r--src/syscall/syscall_darwin_arm64.go13
-rw-r--r--src/syscall/syscall_darwin_test.go2
5 files changed, 43 insertions, 14 deletions
diff --git a/src/runtime/sys_darwin_arm.s b/src/runtime/sys_darwin_arm.s
index 6b6437dddd..52f6a94d46 100644
--- a/src/runtime/sys_darwin_arm.s
+++ b/src/runtime/sys_darwin_arm.s
@@ -162,11 +162,15 @@ TEXT runtime·mincore(SB),NOSPLIT,$0
TEXT time·now(SB), 7, $32
MOVW $8(R13), R0 // timeval
MOVW $0, R1 // zone
+ MOVW $0, R2 // see issue 16570
MOVW $SYS_gettimeofday, R12
SWI $0x80 // Note: R0 is tv_sec, R1 is tv_usec
-
+ CMP $0, R0
+ BNE inreg
+ MOVW 8(R13), R0
+ MOVW 12(R13), R1
+inreg:
MOVW R1, R2 // usec
-
MOVW R0, sec+0(FP)
MOVW $0, R1
MOVW R1, loc+4(FP)
@@ -178,9 +182,14 @@ TEXT time·now(SB), 7, $32
TEXT runtime·nanotime(SB),NOSPLIT,$32
MOVW $8(R13), R0 // timeval
MOVW $0, R1 // zone
+ MOVW $0, R2 // see issue 16570
MOVW $SYS_gettimeofday, R12
SWI $0x80 // Note: R0 is tv_sec, R1 is tv_usec
-
+ CMP $0, R0
+ BNE inreg
+ MOVW 8(R13), R0
+ MOVW 12(R13), R1
+inreg:
MOVW R1, R2
MOVW $1000000000, R3
MULLU R0, R3, (R1, R0)
diff --git a/src/runtime/sys_darwin_arm64.s b/src/runtime/sys_darwin_arm64.s
index a3b851d2fc..8e6b5b1ebf 100644
--- a/src/runtime/sys_darwin_arm64.s
+++ b/src/runtime/sys_darwin_arm64.s
@@ -155,9 +155,14 @@ TEXT time·now(SB),NOSPLIT,$40-12
MOVD RSP, R0 // timeval
MOVD R0, R9 // this is how dyld calls gettimeofday
MOVW $0, R1 // zone
+ MOVD $0, R2 // see issue 16570
MOVW $SYS_gettimeofday, R16
SVC $0x80 // Note: x0 is tv_sec, w1 is tv_usec
-
+ CMP $0, R0
+ BNE inreg
+ MOVD 0(RSP), R0
+ MOVW 8(RSP), R1
+inreg:
MOVD R0, sec+0(FP)
MOVW $1000, R3
MUL R3, R1
@@ -168,9 +173,14 @@ TEXT runtime·nanotime(SB),NOSPLIT,$40
MOVD RSP, R0 // timeval
MOVD R0, R9 // this is how dyld calls gettimeofday
MOVW $0, R1 // zone
+ MOVD $0, R2 // see issue 16570
MOVW $SYS_gettimeofday, R16
SVC $0x80 // Note: x0 is tv_sec, w1 is tv_usec
-
+ CMP $0, R0
+ BNE inreg
+ MOVD 0(RSP), R0
+ MOVW 8(RSP), R1
+inreg:
MOVW $1000000000, R3
MUL R3, R0
MOVW $1000, R3
diff --git a/src/syscall/syscall_darwin_arm.go b/src/syscall/syscall_darwin_arm.go
index c302d83131..fe431039f4 100644
--- a/src/syscall/syscall_darwin_arm.go
+++ b/src/syscall/syscall_darwin_arm.go
@@ -26,14 +26,19 @@ func NsecToTimeval(nsec int64) (tv Timeval) {
}
//sysnb gettimeofday(tp *Timeval) (sec int32, usec int32, err error)
-func Gettimeofday(tv *Timeval) (err error) {
+func Gettimeofday(tv *Timeval) error {
// The tv passed to gettimeofday must be non-nil
// but is otherwise unused. The answers come back
// in the two registers.
sec, usec, err := gettimeofday(tv)
- tv.Sec = int32(sec)
- tv.Usec = int32(usec)
- return err
+ if err != nil {
+ return err
+ }
+ if sec != 0 || usec != 0 {
+ tv.Sec = int32(sec)
+ tv.Usec = int32(usec)
+ }
+ return nil
}
func SetKevent(k *Kevent_t, fd, mode, flags int) {
diff --git a/src/syscall/syscall_darwin_arm64.go b/src/syscall/syscall_darwin_arm64.go
index 29f40d4229..d396e25332 100644
--- a/src/syscall/syscall_darwin_arm64.go
+++ b/src/syscall/syscall_darwin_arm64.go
@@ -26,14 +26,19 @@ func NsecToTimeval(nsec int64) (tv Timeval) {
}
//sysnb gettimeofday(tp *Timeval) (sec int64, usec int32, err error)
-func Gettimeofday(tv *Timeval) (err error) {
+func Gettimeofday(tv *Timeval) error {
// The tv passed to gettimeofday must be non-nil
// but is otherwise unused. The answers come back
// in the two registers.
sec, usec, err := gettimeofday(tv)
- tv.Sec = sec
- tv.Usec = usec
- return err
+ if err != nil {
+ return err
+ }
+ if sec != 0 || usec != 0 {
+ tv.Sec = sec
+ tv.Usec = usec
+ }
+ return nil
}
func SetKevent(k *Kevent_t, fd, mode, flags int) {
diff --git a/src/syscall/syscall_darwin_test.go b/src/syscall/syscall_darwin_test.go
index dd0e32b968..cea5636d07 100644
--- a/src/syscall/syscall_darwin_test.go
+++ b/src/syscall/syscall_darwin_test.go
@@ -3,7 +3,7 @@
// license that can be found in the LICENSE file.
// +build darwin
-// +build amd64 386
+// +build amd64 386 arm arm64
package syscall_test