Skip to content

Commit ea4b785

Browse files
author
Elias Naur
committed
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 <[email protected]> Run-TryBot: Elias Naur <[email protected]> TryBot-Result: Gobot Gobot <[email protected]>
1 parent ac47f66 commit ea4b785

File tree

3 files changed

+61
-22
lines changed

3 files changed

+61
-22
lines changed

src/runtime/rt0_darwin_arm.s

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,15 @@ TEXT _rt0_arm_darwin(SB),7,$-4
1616
//
1717
// Note that all currently shipping darwin/arm platforms require
1818
// cgo and do not support c-shared.
19-
TEXT _rt0_arm_darwin_lib(SB),NOSPLIT,$0
20-
// R11 is REGTMP, reserved for liblink. It is used below to
21-
// move R0/R1 into globals. However in the darwin ARMv7 calling
22-
// convention, it is a callee-saved register. So we save it to a
23-
// temporary register.
24-
MOVW R11, R2
19+
TEXT _rt0_arm_darwin_lib(SB),NOSPLIT,$32
20+
// Preserve callee-save registers.
21+
MOVW R4, 12(R13)
22+
MOVW R5, 16(R13)
23+
MOVW R6, 20(R13)
24+
MOVW R7, 24(R13)
25+
MOVW R8, 28(R13)
26+
MOVW R11, 32(R13)
27+
2528
MOVW R0, _rt0_arm_darwin_lib_argc<>(SB)
2629
MOVW R1, _rt0_arm_darwin_lib_argv<>(SB)
2730

@@ -35,9 +38,8 @@ TEXT _rt0_arm_darwin_lib(SB),NOSPLIT,$0
3538
B.EQ nocgo
3639
MOVW $_rt0_arm_darwin_lib_go(SB), R0
3740
MOVW $0, R1
38-
MOVW R2, R11
3941
BL (R3)
40-
RET
42+
B rr
4143
nocgo:
4244
MOVW $0x400000, R0
4345
MOVW R0, (R13) // stacksize
@@ -46,10 +48,18 @@ nocgo:
4648
MOVW $0, R0
4749
MOVW R0, 8(R13) // fnarg
4850
MOVW $runtime·newosproc0(SB), R3
49-
MOVW R2, R11
5051
BL (R3)
52+
rr:
53+
// Restore callee-save registers and return.
54+
MOVW 12(R13), R4
55+
MOVW 16(R13), R5
56+
MOVW 20(R13), R6
57+
MOVW 24(R13), R7
58+
MOVW 28(R13), R8
59+
MOVW 32(R13), R11
5160
RET
5261

62+
5363
TEXT _rt0_arm_darwin_lib_go(SB),NOSPLIT,$0
5464
MOVW _rt0_arm_darwin_lib_argc<>(SB), R0
5565
MOVW _rt0_arm_darwin_lib_argv<>(SB), R1

src/runtime/rt0_darwin_arm64.s

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,17 @@ TEXT _rt0_arm64_darwin(SB),NOSPLIT,$-8
1616
//
1717
// Note that all currently shipping darwin/arm64 platforms require
1818
// cgo and do not support c-shared.
19-
TEXT _rt0_arm64_darwin_lib(SB),NOSPLIT,$0
20-
// R27 is REGTMP, reserved for liblink. It is used below to
21-
// move R0/R1 into globals. However in the standard ARM64 calling
22-
// convention, it is a callee-saved register. So we save it to a
23-
// temporary register.
24-
MOVD R27, R7
19+
TEXT _rt0_arm64_darwin_lib(SB),NOSPLIT,$88
20+
// Preserve callee-save registers.
21+
MOVD R19, 24(RSP)
22+
MOVD R20, 32(RSP)
23+
MOVD R21, 40(RSP)
24+
MOVD R22, 48(RSP)
25+
MOVD R23, 56(RSP)
26+
MOVD R24, 64(RSP)
27+
MOVD R25, 72(RSP)
28+
MOVD R26, 80(RSP)
29+
MOVD R27, 88(RSP)
2530

2631
MOVD R0, _rt0_arm64_darwin_lib_argc<>(SB)
2732
MOVD R1, _rt0_arm64_darwin_lib_argv<>(SB)
@@ -36,7 +41,16 @@ TEXT _rt0_arm64_darwin_lib(SB),NOSPLIT,$0
3641
MOVD $0, R1
3742
BL (R4)
3843

39-
MOVD R7, R27
44+
// Restore callee-save registers.
45+
MOVD 24(RSP), R19
46+
MOVD 32(RSP), R20
47+
MOVD 40(RSP), R21
48+
MOVD 48(RSP), R22
49+
MOVD 56(RSP), R23
50+
MOVD 64(RSP), R24
51+
MOVD 72(RSP), R25
52+
MOVD 80(RSP), R26
53+
MOVD 88(RSP), R27
4054
RET
4155

4256
TEXT _rt0_arm64_darwin_lib_go(SB),NOSPLIT,$0

src/runtime/rt0_linux_arm64.s

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,17 @@ TEXT _rt0_arm64_linux(SB),NOSPLIT,$-8
1111

1212
// When building with -buildmode=c-shared, this symbol is called when the shared
1313
// library is loaded.
14-
TEXT _rt0_arm64_linux_lib(SB),NOSPLIT,$40
15-
// R27 is REGTMP, reserved for liblink. It is used below to
16-
// move R0/R1 into globals. However in the standard ARM64 calling
17-
// convention, it is a callee-saved register.
18-
MOVD R27, 24(RSP)
14+
TEXT _rt0_arm64_linux_lib(SB),NOSPLIT,$88
15+
// Preserve callee-save registers.
16+
MOVD R19, 24(RSP)
17+
MOVD R20, 32(RSP)
18+
MOVD R21, 40(RSP)
19+
MOVD R22, 48(RSP)
20+
MOVD R23, 56(RSP)
21+
MOVD R24, 64(RSP)
22+
MOVD R25, 72(RSP)
23+
MOVD R26, 80(RSP)
24+
MOVD R27, 88(RSP)
1925

2026
MOVD R0, _rt0_arm64_linux_lib_argc<>(SB)
2127
MOVD R1, _rt0_arm64_linux_lib_argv<>(SB)
@@ -42,7 +48,16 @@ nocgo:
4248
BL (R4)
4349

4450
restore:
45-
MOVD 24(RSP), R27
51+
// Restore callee-save registers.
52+
MOVD 24(RSP), R19
53+
MOVD 32(RSP), R20
54+
MOVD 40(RSP), R21
55+
MOVD 48(RSP), R22
56+
MOVD 56(RSP), R23
57+
MOVD 64(RSP), R24
58+
MOVD 72(RSP), R25
59+
MOVD 80(RSP), R26
60+
MOVD 88(RSP), R27
4661
RET
4762

4863
TEXT _rt0_arm64_linux_lib_go(SB),NOSPLIT,$0

0 commit comments

Comments
 (0)