[committed 3/3] RISC-V: save and restore ssp on setjmp/longjmp
Kito Cheng via Newlib <[email protected]> Mon, 22 Jun 2026 18:52:02 +0800
| Newsgroups | gmane.comp.lib.newlib |
|---|---|
| Message-ID | <[email protected]> |
From: Jesse Huang <[email protected]> --- newlib/libc/include/machine/setjmp.h | 11 +++++-- newlib/libc/machine/riscv/setjmp.S | 43 ++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 2 deletions(-) diff --git a/newlib/libc/include/machine/setjmp.h b/newlib/libc/include/machine/setjmp.h index ab820ed94..4e74bdb0f 100644 --- a/newlib/libc/include/machine/setjmp.h +++ b/newlib/libc/include/machine/setjmp.h @@ -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__ diff --git a/newlib/libc/machine/riscv/setjmp.S b/newlib/libc/machine/riscv/setjmp.S index a29c15f29..336ac5b4e 100644 --- a/newlib/libc/machine/riscv/setjmp.S +++ b/newlib/libc/machine/riscv/setjmp.S @@ -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 -- 2.54.0