aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/asm_arm.s
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2021-02-01 22:58:28 -0500
committerRuss Cox <rsc@golang.org>2021-02-19 00:02:06 +0000
commit01f05d8ff1a88c4a63bdaaff5a095a92ce476f58 (patch)
tree6c853387466cc13722025b1e5f4c880d0031960e /src/runtime/asm_arm.s
parent229695a2833ead7bbee53071f52f34e2ce1c2802 (diff)
downloadgo-01f05d8ff1a88c4a63bdaaff5a095a92ce476f58.tar.gz
go-01f05d8ff1a88c4a63bdaaff5a095a92ce476f58.zip
runtime: unify asmcgocall and systemstack traceback setup
Both asmcgocall and systemstack need to save the calling Go code's context for use by traceback, but they do it differently. Systemstack's appraoch is better, because it doesn't require a special case in traceback. So make them both use that. While we are here, the fake mstart caller in systemstack is no longer needed and can be removed. (traceback knows to stop in systemstack because of the writes to SP.) Also remove the fake mstarts in sys_windows_*.s. And while we are there, fix the control flow guard code in sys_windows_arm.s. The current code is using pointers to a stack frame that technically is gone once we hit the RET instruction. Clearly it's working OK, but better not to depend on data below SP being preserved, even for just a few instructions. Store the value we need in other registers instead. (This code is only used for pushing a sigpanic call, which does not actually return to the site of the fault and therefore doesn't need to preserve any of the registers.) This CL is part of a stack adding windows/arm64 support (#36439), intended to land in the Go 1.17 cycle. This CL is, however, not windows/arm64-specific. It is cleanup meant to make the port (and future ports) easier. Change-Id: Id1e3ef5e54f7ad786e4b87043f2626eba7c3bbd9 Reviewed-on: https://go-review.googlesource.com/c/go/+/288799 Trust: Russ Cox <rsc@golang.org> Reviewed-by: Cherry Zhang <cherryyz@google.com>
Diffstat (limited to 'src/runtime/asm_arm.s')
-rw-r--r--src/runtime/asm_arm.s34
1 files changed, 15 insertions, 19 deletions
diff --git a/src/runtime/asm_arm.s b/src/runtime/asm_arm.s
index 109030aada..c8c53e70db 100644
--- a/src/runtime/asm_arm.s
+++ b/src/runtime/asm_arm.s
@@ -305,24 +305,14 @@ TEXT runtime·systemstack(SB),NOSPLIT,$0-4
switch:
// save our state in g->sched. Pretend to
// be systemstack_switch if the G stack is scanned.
- MOVW $runtime·systemstack_switch(SB), R3
- ADD $4, R3, R3 // get past push {lr}
- MOVW R3, (g_sched+gobuf_pc)(g)
- MOVW R13, (g_sched+gobuf_sp)(g)
- MOVW LR, (g_sched+gobuf_lr)(g)
- MOVW g, (g_sched+gobuf_g)(g)
+ BL gosave_systemstack_switch<>(SB)
// switch to g0
MOVW R0, R5
MOVW R2, R0
BL setg<>(SB)
MOVW R5, R0
- MOVW (g_sched+gobuf_sp)(R2), R3
- // make it look like mstart called systemstack on g0, to stop traceback
- SUB $4, R3, R3
- MOVW $runtime·mstart(SB), R4
- MOVW R4, 0(R3)
- MOVW R3, R13
+ MOVW (g_sched+gobuf_sp)(R2), R13
// call target function
MOVW R0, R7
@@ -537,19 +527,25 @@ TEXT runtime·jmpdefer(SB),NOSPLIT,$0-8
MOVW 0(R7), R1
B (R1)
-// Save state of caller into g->sched. Smashes R11.
-TEXT gosave<>(SB),NOSPLIT|NOFRAME,$0
- MOVW LR, (g_sched+gobuf_pc)(g)
+// Save state of caller into g->sched,
+// but using fake PC from systemstack_switch.
+// Must only be called from functions with no locals ($0)
+// or else unwinding from systemstack_switch is incorrect.
+// Smashes R11.
+TEXT gosave_systemstack_switch<>(SB),NOSPLIT|NOFRAME,$0
+ MOVW $runtime·systemstack_switch(SB), R11
+ ADD $4, R11 // get past push {lr}
+ MOVW R11, (g_sched+gobuf_pc)(g)
MOVW R13, (g_sched+gobuf_sp)(g)
+ MOVW g, (g_sched+gobuf_g)(g)
MOVW $0, R11
MOVW R11, (g_sched+gobuf_lr)(g)
MOVW R11, (g_sched+gobuf_ret)(g)
- MOVW R11, (g_sched+gobuf_ctxt)(g)
// Assert ctxt is zero. See func save.
MOVW (g_sched+gobuf_ctxt)(g), R11
- CMP $0, R11
+ TST R11, R11
B.EQ 2(PC)
- CALL runtime·badctxt(SB)
+ BL runtime·badctxt(SB)
RET
// func asmcgocall_no_g(fn, arg unsafe.Pointer)
@@ -590,7 +586,7 @@ TEXT ·asmcgocall(SB),NOSPLIT,$0-12
MOVW m_g0(R8), R3
CMP R3, g
BEQ nosave
- BL gosave<>(SB)
+ BL gosave_systemstack_switch<>(SB)
MOVW R0, R5
MOVW R3, R0
BL setg<>(SB)