1
0
mirror of https://github.com/golang/go synced 2024-11-19 09:04:41 -07:00

runtime: preserve darwin/arm{,64} callee-save registers

CL 14603 attempted to preserve the callee-save registers for
the darwin/arm runtime initialization routine, but I believe it
wasn't sufficient and resulted in the crash reported in issue

Saving and restoring the registers on the stack the same way
linux/arm does seems more obvious and fixes #14778, so do that.

Even though #14778 is not reproducible on darwin/arm64, I applied
a similar change there, and to linux/arm64 which obeys the same
calling convention.

Finally, this CL is a candidate for a 1.6 minor release for the same
reason CL 14603 was in a 1.5 minor release (as CL 16968). It is
small and only touches the iOS platforms and gomobile on darwin/arm
is currently useless without it.

Fixes #14778
Fixes #12590 (again)

Change-Id: I7401daf0bbd7c579a7e84761384a7b763651752a
Reviewed-on: https://go-review.googlesource.com/20621
Reviewed-by: David Crawshaw <crawshaw@golang.org>
Run-TryBot: Elias Naur <elias.naur@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
Elias Naur 2016-03-12 12:13:11 +01:00
parent ac47f66abc
commit ea4b785ae0
3 changed files with 61 additions and 22 deletions

View File

@ -16,12 +16,15 @@ TEXT _rt0_arm_darwin(SB),7,$-4
// //
// Note that all currently shipping darwin/arm platforms require // Note that all currently shipping darwin/arm platforms require
// cgo and do not support c-shared. // cgo and do not support c-shared.
TEXT _rt0_arm_darwin_lib(SB),NOSPLIT,$0 TEXT _rt0_arm_darwin_lib(SB),NOSPLIT,$32
// R11 is REGTMP, reserved for liblink. It is used below to // Preserve callee-save registers.
// move R0/R1 into globals. However in the darwin ARMv7 calling MOVW R4, 12(R13)
// convention, it is a callee-saved register. So we save it to a MOVW R5, 16(R13)
// temporary register. MOVW R6, 20(R13)
MOVW R11, R2 MOVW R7, 24(R13)
MOVW R8, 28(R13)
MOVW R11, 32(R13)
MOVW R0, _rt0_arm_darwin_lib_argc<>(SB) MOVW R0, _rt0_arm_darwin_lib_argc<>(SB)
MOVW R1, _rt0_arm_darwin_lib_argv<>(SB) MOVW R1, _rt0_arm_darwin_lib_argv<>(SB)
@ -35,9 +38,8 @@ TEXT _rt0_arm_darwin_lib(SB),NOSPLIT,$0
B.EQ nocgo B.EQ nocgo
MOVW $_rt0_arm_darwin_lib_go(SB), R0 MOVW $_rt0_arm_darwin_lib_go(SB), R0
MOVW $0, R1 MOVW $0, R1
MOVW R2, R11
BL (R3) BL (R3)
RET B rr
nocgo: nocgo:
MOVW $0x400000, R0 MOVW $0x400000, R0
MOVW R0, (R13) // stacksize MOVW R0, (R13) // stacksize
@ -46,10 +48,18 @@ nocgo:
MOVW $0, R0 MOVW $0, R0
MOVW R0, 8(R13) // fnarg MOVW R0, 8(R13) // fnarg
MOVW $runtime·newosproc0(SB), R3 MOVW $runtime·newosproc0(SB), R3
MOVW R2, R11
BL (R3) BL (R3)
rr:
// Restore callee-save registers and return.
MOVW 12(R13), R4
MOVW 16(R13), R5
MOVW 20(R13), R6
MOVW 24(R13), R7
MOVW 28(R13), R8
MOVW 32(R13), R11
RET RET
TEXT _rt0_arm_darwin_lib_go(SB),NOSPLIT,$0 TEXT _rt0_arm_darwin_lib_go(SB),NOSPLIT,$0
MOVW _rt0_arm_darwin_lib_argc<>(SB), R0 MOVW _rt0_arm_darwin_lib_argc<>(SB), R0
MOVW _rt0_arm_darwin_lib_argv<>(SB), R1 MOVW _rt0_arm_darwin_lib_argv<>(SB), R1

View File

@ -16,12 +16,17 @@ TEXT _rt0_arm64_darwin(SB),NOSPLIT,$-8
// //
// Note that all currently shipping darwin/arm64 platforms require // Note that all currently shipping darwin/arm64 platforms require
// cgo and do not support c-shared. // cgo and do not support c-shared.
TEXT _rt0_arm64_darwin_lib(SB),NOSPLIT,$0 TEXT _rt0_arm64_darwin_lib(SB),NOSPLIT,$88
// R27 is REGTMP, reserved for liblink. It is used below to // Preserve callee-save registers.
// move R0/R1 into globals. However in the standard ARM64 calling MOVD R19, 24(RSP)
// convention, it is a callee-saved register. So we save it to a MOVD R20, 32(RSP)
// temporary register. MOVD R21, 40(RSP)
MOVD R27, R7 MOVD R22, 48(RSP)
MOVD R23, 56(RSP)
MOVD R24, 64(RSP)
MOVD R25, 72(RSP)
MOVD R26, 80(RSP)
MOVD R27, 88(RSP)
MOVD R0, _rt0_arm64_darwin_lib_argc<>(SB) MOVD R0, _rt0_arm64_darwin_lib_argc<>(SB)
MOVD R1, _rt0_arm64_darwin_lib_argv<>(SB) MOVD R1, _rt0_arm64_darwin_lib_argv<>(SB)
@ -36,7 +41,16 @@ TEXT _rt0_arm64_darwin_lib(SB),NOSPLIT,$0
MOVD $0, R1 MOVD $0, R1
BL (R4) BL (R4)
MOVD R7, R27 // Restore callee-save registers.
MOVD 24(RSP), R19
MOVD 32(RSP), R20
MOVD 40(RSP), R21
MOVD 48(RSP), R22
MOVD 56(RSP), R23
MOVD 64(RSP), R24
MOVD 72(RSP), R25
MOVD 80(RSP), R26
MOVD 88(RSP), R27
RET RET
TEXT _rt0_arm64_darwin_lib_go(SB),NOSPLIT,$0 TEXT _rt0_arm64_darwin_lib_go(SB),NOSPLIT,$0

View File

@ -11,11 +11,17 @@ TEXT _rt0_arm64_linux(SB),NOSPLIT,$-8
// When building with -buildmode=c-shared, this symbol is called when the shared // When building with -buildmode=c-shared, this symbol is called when the shared
// library is loaded. // library is loaded.
TEXT _rt0_arm64_linux_lib(SB),NOSPLIT,$40 TEXT _rt0_arm64_linux_lib(SB),NOSPLIT,$88
// R27 is REGTMP, reserved for liblink. It is used below to // Preserve callee-save registers.
// move R0/R1 into globals. However in the standard ARM64 calling MOVD R19, 24(RSP)
// convention, it is a callee-saved register. MOVD R20, 32(RSP)
MOVD R27, 24(RSP) MOVD R21, 40(RSP)
MOVD R22, 48(RSP)
MOVD R23, 56(RSP)
MOVD R24, 64(RSP)
MOVD R25, 72(RSP)
MOVD R26, 80(RSP)
MOVD R27, 88(RSP)
MOVD R0, _rt0_arm64_linux_lib_argc<>(SB) MOVD R0, _rt0_arm64_linux_lib_argc<>(SB)
MOVD R1, _rt0_arm64_linux_lib_argv<>(SB) MOVD R1, _rt0_arm64_linux_lib_argv<>(SB)
@ -42,7 +48,16 @@ nocgo:
BL (R4) BL (R4)
restore: restore:
MOVD 24(RSP), R27 // Restore callee-save registers.
MOVD 24(RSP), R19
MOVD 32(RSP), R20
MOVD 40(RSP), R21
MOVD 48(RSP), R22
MOVD 56(RSP), R23
MOVD 64(RSP), R24
MOVD 72(RSP), R25
MOVD 80(RSP), R26
MOVD 88(RSP), R27
RET RET
TEXT _rt0_arm64_linux_lib_go(SB),NOSPLIT,$0 TEXT _rt0_arm64_linux_lib_go(SB),NOSPLIT,$0