aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/sys_linux_arm64.s
diff options
context:
space:
mode:
Diffstat (limited to 'src/runtime/sys_linux_arm64.s')
-rw-r--r--src/runtime/sys_linux_arm64.s34
1 files changed, 32 insertions, 2 deletions
diff --git a/src/runtime/sys_linux_arm64.s b/src/runtime/sys_linux_arm64.s
index b23e3b9a11..198a5bacef 100644
--- a/src/runtime/sys_linux_arm64.s
+++ b/src/runtime/sys_linux_arm64.s
@@ -214,6 +214,13 @@ TEXT runtime·walltime1(SB),NOSPLIT,$24-12
MOVD g_m(g), R21 // R21 = m
// Set vdsoPC and vdsoSP for SIGPROF traceback.
+ // Save the old values on stack and restore them on exit,
+ // so this function is reentrant.
+ MOVD m_vdsoPC(R21), R2
+ MOVD m_vdsoSP(R21), R3
+ MOVD R2, 8(RSP)
+ MOVD R3, 16(RSP)
+
MOVD LR, m_vdsoPC(R21)
MOVD R20, m_vdsoSP(R21)
@@ -269,7 +276,15 @@ finish:
MOVD 8(RSP), R5 // nsec
MOVD R20, RSP // restore SP
- MOVD $0, m_vdsoSP(R21) // clear vdsoSP
+ // Restore vdsoPC, vdsoSP
+ // We don't worry about being signaled between the two stores.
+ // If we are not in a signal handler, we'll restore vdsoSP to 0,
+ // and no one will care about vdsoPC. If we are in a signal handler,
+ // we cannot receive another signal.
+ MOVD 16(RSP), R1
+ MOVD R1, m_vdsoSP(R21)
+ MOVD 8(RSP), R1
+ MOVD R1, m_vdsoPC(R21)
MOVD R3, sec+0(FP)
MOVW R5, nsec+8(FP)
@@ -282,6 +297,13 @@ TEXT runtime·nanotime1(SB),NOSPLIT,$24-8
MOVD g_m(g), R21 // R21 = m
// Set vdsoPC and vdsoSP for SIGPROF traceback.
+ // Save the old values on stack and restore them on exit,
+ // so this function is reentrant.
+ MOVD m_vdsoPC(R21), R2
+ MOVD m_vdsoSP(R21), R3
+ MOVD R2, 8(RSP)
+ MOVD R3, 16(RSP)
+
MOVD LR, m_vdsoPC(R21)
MOVD R20, m_vdsoSP(R21)
@@ -337,7 +359,15 @@ finish:
MOVD 8(RSP), R5 // nsec
MOVD R20, RSP // restore SP
- MOVD $0, m_vdsoSP(R21) // clear vdsoSP
+ // Restore vdsoPC, vdsoSP
+ // We don't worry about being signaled between the two stores.
+ // If we are not in a signal handler, we'll restore vdsoSP to 0,
+ // and no one will care about vdsoPC. If we are in a signal handler,
+ // we cannot receive another signal.
+ MOVD 16(RSP), R1
+ MOVD R1, m_vdsoSP(R21)
+ MOVD 8(RSP), R1
+ MOVD R1, m_vdsoPC(R21)
// sec is in R3, nsec in R5
// return nsec in R3