aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/sys_linux_arm.s
diff options
context:
space:
mode:
Diffstat (limited to 'src/runtime/sys_linux_arm.s')
-rw-r--r--src/runtime/sys_linux_arm.s36
1 files changed, 32 insertions, 4 deletions
diff --git a/src/runtime/sys_linux_arm.s b/src/runtime/sys_linux_arm.s
index e103da56dc..475f52344c 100644
--- a/src/runtime/sys_linux_arm.s
+++ b/src/runtime/sys_linux_arm.s
@@ -242,7 +242,7 @@ TEXT runtime·mincore(SB),NOSPLIT,$0
MOVW R0, ret+12(FP)
RET
-TEXT runtime·walltime1(SB),NOSPLIT,$0-12
+TEXT runtime·walltime1(SB),NOSPLIT,$8-12
// We don't know how much stack space the VDSO code will need,
// so switch to g0.
@@ -252,6 +252,13 @@ TEXT runtime·walltime1(SB),NOSPLIT,$0-12
MOVW g_m(g), R5 // R5 is unchanged by C code.
// Set vdsoPC and vdsoSP for SIGPROF traceback.
+ // Save the old values on stack and restore them on exit,
+ // so this function is reentrant.
+ MOVW m_vdsoPC(R5), R1
+ MOVW m_vdsoSP(R5), R2
+ MOVW R1, 4(R13)
+ MOVW R2, 8(R13)
+
MOVW LR, m_vdsoPC(R5)
MOVW R13, m_vdsoSP(R5)
@@ -312,8 +319,15 @@ finish:
MOVW 12(R13), R2 // nsec
MOVW R4, R13 // Restore real SP
- MOVW $0, R1
+ // 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.
+ MOVW 8(R13), R1
MOVW R1, m_vdsoSP(R5)
+ MOVW 4(R13), R1
+ MOVW R1, m_vdsoPC(R5)
MOVW R0, sec_lo+0(FP)
MOVW R1, sec_hi+4(FP)
@@ -321,7 +335,7 @@ finish:
RET
// int64 nanotime1(void)
-TEXT runtime·nanotime1(SB),NOSPLIT,$0-8
+TEXT runtime·nanotime1(SB),NOSPLIT,$8-8
// Switch to g0 stack. See comment above in runtime·walltime.
// Save old SP. Use R13 instead of SP to avoid linker rewriting the offsets.
@@ -330,6 +344,13 @@ TEXT runtime·nanotime1(SB),NOSPLIT,$0-8
MOVW g_m(g), R5 // R5 is unchanged by C code.
// Set vdsoPC and vdsoSP for SIGPROF traceback.
+ // Save the old values on stack and restore them on exit,
+ // so this function is reentrant.
+ MOVW m_vdsoPC(R5), R1
+ MOVW m_vdsoSP(R5), R2
+ MOVW R1, 4(R13)
+ MOVW R2, 8(R13)
+
MOVW LR, m_vdsoPC(R5)
MOVW R13, m_vdsoSP(R5)
@@ -390,8 +411,15 @@ finish:
MOVW 12(R13), R2 // nsec
MOVW R4, R13 // Restore real SP
- MOVW $0, R4
+ // 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.
+ MOVW 8(R13), R4
MOVW R4, m_vdsoSP(R5)
+ MOVW 4(R13), R4
+ MOVW R4, m_vdsoPC(R5)
MOVW $1000000000, R3
MULLU R0, R3, (R1, R0)