diff options
author | Monk Chiang <monk.chiang@sifive.com> | 2024-11-15 13:38:48 +0800 |
---|---|---|
committer | Monk Chiang <monk.chiang@sifive.com> | 2025-01-17 10:49:16 +0800 |
commit | dc76aa0e4d5398104b6b26f08b46524b97de5100 (patch) | |
tree | 7210fc03f9544ca682238548dd4768490651e16e /gcc/testsuite/gcc.target/riscv | |
parent | 29da6a642402ac64002f5edeab268606b4637103 (diff) | |
download | gcc-dc76aa0e4d5398104b6b26f08b46524b97de5100.zip gcc-dc76aa0e4d5398104b6b26f08b46524b97de5100.tar.gz gcc-dc76aa0e4d5398104b6b26f08b46524b97de5100.tar.bz2 |
RISC-V: Add Zicfiss ISA extension.
This patch is implemented according to the RISC-V CFI specification.
It supports the generation of shadow stack instructions in the prologue,
epilogue, non-local gotos, and unwinding.
RISC-V CFI SPEC: https://github.com/riscv/riscv-cfi
gcc/ChangeLog:
* common/config/riscv/riscv-common.cc: Add ZICFISS ISA string.
* config/riscv/predicates.md: New predicate x1x5_operand.
* config/riscv/riscv.cc
(riscv_expand_prologue): Insert shadow stack instructions.
(riscv_expand_epilogue): Likewise.
(riscv_for_each_saved_reg): Assign t0 or ra register for
sspopchk instruction.
(need_shadow_stack_push_pop_p): New function. Omit shadow
stack operation on leaf function.
* config/riscv/riscv.h
(need_shadow_stack_push_pop_p): Define.
* config/riscv/riscv.md: Add shadow stack patterns.
(save_stack_nonlocal): Add shadow stack instructions for setjump.
(restore_stack_nonlocal): Add shadow stack instructions for longjump.
* config/riscv/riscv.opt (TARGET_ZICFISS): Define.
libgcc/ChangeLog:
* config/riscv/linux-unwind.h: Include shadow-stack-unwind.h.
* config/riscv/shadow-stack-unwind.h
(_Unwind_Frames_Extra): Define.
(_Unwind_Frames_Increment): Define.
gcc/testsuite/ChangeLog:
* gcc.target/riscv/ssp-1.c: New test.
* gcc.target/riscv/ssp-2.c: New test.
Co-Developed-by: Greg McGary <gkm@rivosinc.com>,
Kito Cheng <kito.cheng@gmail.com>
Diffstat (limited to 'gcc/testsuite/gcc.target/riscv')
-rw-r--r-- | gcc/testsuite/gcc.target/riscv/ssp-1.c | 41 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/riscv/ssp-2.c | 10 |
2 files changed, 51 insertions, 0 deletions
diff --git a/gcc/testsuite/gcc.target/riscv/ssp-1.c b/gcc/testsuite/gcc.target/riscv/ssp-1.c new file mode 100644 index 0000000..abf47ec --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/ssp-1.c @@ -0,0 +1,41 @@ +/* { dg-do compile { target { riscv64*-*-* } } } */ +/* { dg-options "-O2 -march=rv64gc_zicfiss -mabi=lp64d" } */ +/* { dg-skip-if "" { *-*-* } { "-O0" } } */ +struct ad { + void *ae; +}; +struct af { + union { + int *ai; + int *aj; + struct ad *ak; + } u; + struct { + struct { + long al : 1; + long am : 1; + long : 21; + } b; + long i; + } s; +}; +void fdes (struct af *, void *, long *); + +void foo (struct af *bv, long *bw) { + bw[0] = bw[1] = 0; + if (bv->s.b.al) + fdes (bv, bv->u.ak->ae, bw); + else if (bv->s.b.am) { + int **p = (int**)bv->u.aj; + for (; *p; ++p) + fdes (bv, *p, bw); + } else + fdes (bv, bv->u.ai, bw); +} + +/* { dg-final { scan-assembler-times "ld\tt0" 1 } } */ +/* { dg-final { scan-assembler-times "sspopchk\tt0" 1 } } */ +/* { dg-final { scan-assembler-times "jr\tt0" 1 } } */ +/* { dg-final { scan-assembler-times "ld\tra" 2 } } */ +/* { dg-final { scan-assembler-times "sspopchk\tra" 2 } } */ +/* { dg-final { scan-assembler-times "tail" 2 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/ssp-2.c b/gcc/testsuite/gcc.target/riscv/ssp-2.c new file mode 100644 index 0000000..7c60983 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/ssp-2.c @@ -0,0 +1,10 @@ +/* { dg-do compile { target { riscv64*-*-* } } } */ +/* { dg-options "-O0 -march=rv64gc_zicfiss -mabi=lp64d" } */ + +void __attribute__ ((interrupt)) +foo (void) +{ +} +/* { dg-final { scan-assembler-times "sd\tra" 1 } } */ +/* { dg-final { scan-assembler-times "ld\tra" 1 } } */ +/* { dg-final { scan-assembler-times "sspopchk\tra" 1 } } */ |