[committed,3/3] RISC-V: save and restore ssp on setjmp/longjmp
Commit Message
From: Jesse Huang <jesse.huang@sifive.com>
---
newlib/libc/include/machine/setjmp.h | 11 +++++--
newlib/libc/machine/riscv/setjmp.S | 43 ++++++++++++++++++++++++++++
2 files changed, 52 insertions(+), 2 deletions(-)
@@ -431,10 +431,17 @@ _BEGIN_STD_C
otherwise in rv32imafd, store/restore FPR may mis-align. */
#define _JBTYPE long long
#ifdef __riscv_32e
-#define _JBLEN ((4*sizeof(long))/sizeof(long))
+#define __JBLEN ((4*sizeof(long))/sizeof(long))
#else
-#define _JBLEN ((14*sizeof(long) + 12*sizeof(double))/sizeof(long))
+#define __JBLEN ((14*sizeof(long) + 12*sizeof(double))/sizeof(long))
#endif
+
+#ifdef __riscv_shadow_stack
+#define _JBLEN (__JBLEN + 1)
+#else
+#define _JBLEN (__JBLEN)
+#endif
+
#endif
#ifdef __CSKYABIV2__
@@ -60,6 +60,18 @@ ENTRY(setjmp)
FREG_S fs11,14*SZREG+11*SZFREG(a0)
#endif
+#ifdef __riscv_shadow_stack
+ /* read ssp into t0 */
+ ssrdp t0
+# ifndef __riscv_float_abi_soft
+ REG_S t0, 14*SZREG+12*SZFREG(a0)
+# elif defined (__riscv_32e)
+ REG_S t0, 4*SZREG(a0)
+# else
+ REG_S t0, 14*SZREG(a0)
+# endif
+#endif
+
li a0, 0
ret
END(setjmp)
@@ -110,6 +122,37 @@ ENTRY(longjmp)
FREG_L fs9, 14*SZREG+ 9*SZFREG(a0)
FREG_L fs10,14*SZREG+10*SZFREG(a0)
FREG_L fs11,14*SZREG+11*SZFREG(a0)
+#endif
+#ifdef __riscv_shadow_stack
+ /* read ssp into t0 */
+ ssrdp t0
+ /* skip unwinding if ss is not enabled */
+ beqz t0, .Lunwind_fin
+# ifndef __riscv_float_abi_soft
+ REG_L t1, 14*SZREG+12*SZFREG(a0)
+# elif defined (__riscv_32e)
+ REG_L t0, 4*SZREG(a0)
+# else
+ REG_L t1, 14*SZREG(a0)
+# endif
+.Lunwind:
+ /* should not be taken in normal condition */
+ bleu t1, t0, .Lunwind_fin
+ /* The unwinding algorithm came from the zicfiss spec, increase ssp
+ by at most a page size to ensure always run into a guard page
+ before accidentally point to another legal shadow stack page */
+ /* t0 = (t1 - t0 >= 4096) ? t0 + 4096 : t1 */
+ lui a0, 1
+ add t0, t0, a0
+ bleu t0, t1, 1f
+ mv t0, t1
+1:
+ csrw ssp, t0
+ /* Test if the location pointed by ssp is legal */
+ sspush x5
+ sspopchk x5
+ j .Lunwind
+.Lunwind_fin:
#endif
seqz a0, a1