diff options
Diffstat (limited to 'src/runtime/sys_linux_arm64.s')
| -rw-r--r-- | src/runtime/sys_linux_arm64.s | 34 |
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 |
