aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMonk Chiang <monk.chiang@sifive.com>2024-11-15 18:18:36 +0800
committerMonk Chiang <monk.chiang@sifive.com>2025-01-17 10:55:07 +0800
commit59a869d7196132ae5257fcb068508561d3526c7d (patch)
treebaef6b3a5b3b83d1e2694fab4842839fd9209022
parent2b3efe793e9ecf0f98da1daa85a091e931b4ca04 (diff)
downloadgcc-59a869d7196132ae5257fcb068508561d3526c7d.zip
gcc-59a869d7196132ae5257fcb068508561d3526c7d.tar.gz
gcc-59a869d7196132ae5257fcb068508561d3526c7d.tar.bz2
RISC-V: Add -fcf-protection=[full|branch|return] to enable zicfiss, zicfilp.
gcc/ChangeLog: * config/riscv/riscv.cc (is_zicfilp_p): New function. (is_zicfiss_p): New function. * config/riscv/riscv-zicfilp.cc: Update. * config/riscv/riscv.h: Update. * config/riscv/riscv.md: Update. * config/riscv/riscv-c.cc: Add CFI predefine marco. gcc/testsuite/ChangeLog: * c-c++-common/fcf-protection-1.c: Update. * c-c++-common/fcf-protection-2.c: Update. * c-c++-common/fcf-protection-3.c: Update. * c-c++-common/fcf-protection-4.c: Update. * c-c++-common/fcf-protection-5.c: Update. * c-c++-common/fcf-protection-6.c: Update. * c-c++-common/fcf-protection-7.c: Update. * gcc.target/riscv/ssp-1.c: Update. * gcc.target/riscv/ssp-2.c: Update. * gcc.target/riscv/zicfilp-call.c: Update. * gcc.target/riscv/interrupt-no-lpad.c: Update.
-rw-r--r--gcc/config/riscv/riscv-c.cc9
-rw-r--r--gcc/config/riscv/riscv-zicfilp.cc2
-rw-r--r--gcc/config/riscv/riscv.cc52
-rw-r--r--gcc/config/riscv/riscv.h8
-rw-r--r--gcc/config/riscv/riscv.md10
-rw-r--r--gcc/testsuite/c-c++-common/fcf-protection-1.c1
-rw-r--r--gcc/testsuite/c-c++-common/fcf-protection-2.c1
-rw-r--r--gcc/testsuite/c-c++-common/fcf-protection-3.c1
-rw-r--r--gcc/testsuite/c-c++-common/fcf-protection-4.c1
-rw-r--r--gcc/testsuite/c-c++-common/fcf-protection-5.c1
-rw-r--r--gcc/testsuite/c-c++-common/fcf-protection-6.c1
-rw-r--r--gcc/testsuite/c-c++-common/fcf-protection-7.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/interrupt-no-lpad.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/ssp-1.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/ssp-2.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/zicfilp-call.c2
16 files changed, 72 insertions, 24 deletions
diff --git a/gcc/config/riscv/riscv-c.cc b/gcc/config/riscv/riscv-c.cc
index e28d557..7912b10 100644
--- a/gcc/config/riscv/riscv-c.cc
+++ b/gcc/config/riscv/riscv-c.cc
@@ -223,6 +223,15 @@ riscv_cpu_cpp_builtins (cpp_reader *pfile)
/* Define architecture extension test macros. */
builtin_define_with_int_value ("__riscv_arch_test", 1);
+ if (TARGET_ZICFISS && ((flag_cf_protection & CF_RETURN) == CF_RETURN))
+ builtin_define ("__riscv_shadow_stack");
+
+ if (TARGET_ZICFILP && ((flag_cf_protection & CF_BRANCH) == CF_BRANCH))
+ {
+ builtin_define ("__riscv_landing_pad");
+ builtin_define ("__riscv_landing_pad_unlabeled");
+ }
+
const riscv_subset_list *subset_list = riscv_cmdline_subset_list ();
if (!subset_list)
return;
diff --git a/gcc/config/riscv/riscv-zicfilp.cc b/gcc/config/riscv/riscv-zicfilp.cc
index 42b1299..834d6e5 100644
--- a/gcc/config/riscv/riscv-zicfilp.cc
+++ b/gcc/config/riscv/riscv-zicfilp.cc
@@ -150,7 +150,7 @@ public:
/* opt_pass methods: */
virtual bool gate (function *)
{
- return TARGET_ZICFILP;
+ return is_zicfilp_p ();
}
virtual unsigned int execute (function *)
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 37c3431..aa5cb8a 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -6682,7 +6682,7 @@ riscv_legitimize_call_address (rtx addr)
rtx reg = RISCV_CALL_ADDRESS_TEMP (Pmode);
riscv_emit_move (reg, addr);
- if (TARGET_ZICFILP)
+ if (is_zicfilp_p ())
{
rtx sw_guarded = RISCV_CALL_ADDRESS_LPAD (Pmode);
emit_insn (gen_set_guarded (Pmode, reg));
@@ -6692,7 +6692,7 @@ riscv_legitimize_call_address (rtx addr)
return reg;
}
- if (TARGET_ZICFILP && REG_P (addr))
+ if (is_zicfilp_p () && REG_P (addr))
emit_insn (gen_set_lpl (Pmode, const0_rtx));
return addr;
@@ -7508,7 +7508,7 @@ riscv_save_reg_p (unsigned int regno)
if (regno == GP_REGNUM || regno == THREAD_POINTER_REGNUM)
return false;
- if (regno == RETURN_ADDR_REGNUM && TARGET_ZICFISS)
+ if (regno == RETURN_ADDR_REGNUM && is_zicfiss_p ())
return true;
/* We must save every register used in this function. If this is not a
@@ -10340,10 +10340,10 @@ riscv_file_end ()
long GNU_PROPERTY_RISCV_FEATURE_1_AND = 0;
unsigned long feature_1_and = 0;
- if (TARGET_ZICFISS)
+ if (is_zicfilp_p ())
feature_1_and |= 0x1 << 0;
- if (TARGET_ZICFILP)
+ if (is_zicfiss_p ())
feature_1_and |= 0x1 << 1;
if (feature_1_and)
@@ -10403,7 +10403,7 @@ riscv_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
/* Mark the end of the (empty) prologue. */
emit_note (NOTE_INSN_PROLOGUE_END);
- if (TARGET_ZICFILP)
+ if (is_zicfilp_p ())
emit_insn(gen_lpad (const0_rtx));
/* Determine if we can use a sibcall to call FUNCTION directly. */
@@ -10630,6 +10630,20 @@ riscv_override_options_internal (struct gcc_options *opts)
/* Convert -march and -mrvv-vector-bits to a chunks count. */
riscv_vector_chunks = riscv_convert_vector_chunks (opts);
+
+ if (opts->x_flag_cf_protection != CF_NONE)
+ {
+ if ((opts->x_flag_cf_protection & CF_RETURN) == CF_RETURN
+ && !TARGET_ZICFISS)
+ error ("%<-fcf-protection%> is not compatible with this target");
+
+ if ((opts->x_flag_cf_protection & CF_BRANCH) == CF_BRANCH
+ && !TARGET_ZICFILP)
+ error ("%<-fcf-protection%> is not compatible with this target");
+
+ opts->x_flag_cf_protection
+ = (cf_protection_level) (opts->x_flag_cf_protection | CF_SET);
+ }
}
/* Implement TARGET_OPTION_OVERRIDE. */
@@ -10924,7 +10938,7 @@ riscv_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
/* Work out the offsets of the pointers from the start of the
trampoline code. */
- if (!TARGET_ZICFILP)
+ if (!is_zicfilp_p ())
gcc_assert (ARRAY_SIZE (trampoline) * 4 == TRAMPOLINE_CODE_SIZE);
else
gcc_assert (ARRAY_SIZE (trampoline_cfi) * 4 == TRAMPOLINE_CODE_SIZE);
@@ -10952,7 +10966,7 @@ riscv_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
unsigned insn_count = 0;
/* Insert lpad, if zicfilp is enabled. */
- if (TARGET_ZICFILP)
+ if (is_zicfilp_p ())
{
unsigned HOST_WIDE_INT lpad_code;
lpad_code = OPCODE_AUIPC | (0 << SHIFT_RD) | (lp_value << IMM_BITS);
@@ -11014,7 +11028,7 @@ riscv_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
insn_count++;
/* For zicfilp only, insert lui t2, 1, because use jr t0. */
- if (TARGET_ZICFILP)
+ if (is_zicfilp_p ())
{
unsigned HOST_WIDE_INT set_lpl_code;
set_lpl_code = OPCODE_LUI
@@ -11044,7 +11058,7 @@ riscv_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
static_chain_offset = TRAMPOLINE_CODE_SIZE;
target_function_offset = static_chain_offset + GET_MODE_SIZE (ptr_mode);
- if (!TARGET_ZICFILP)
+ if (!is_zicfilp_p ())
{
/* auipc t2, 0
l[wd] t0, (target_function_offset)(t2)
@@ -13959,9 +13973,25 @@ expand_reversed_crc_using_clmul (scalar_mode crc_mode, scalar_mode data_mode,
riscv_emit_move (operands[0], gen_lowpart (crc_mode, a0));
}
+bool is_zicfiss_p ()
+{
+ if (TARGET_ZICFISS && (flag_cf_protection & CF_RETURN))
+ return true;
+
+ return false;
+}
+
+bool is_zicfilp_p ()
+{
+ if (TARGET_ZICFILP && (flag_cf_protection & CF_BRANCH))
+ return true;
+
+ return false;
+}
+
bool need_shadow_stack_push_pop_p ()
{
- return TARGET_ZICFISS && riscv_save_return_addr_reg_p ();
+ return is_zicfiss_p () && riscv_save_return_addr_reg_p ();
}
/* Initialize the GCC target structure. */
diff --git a/gcc/config/riscv/riscv.h b/gcc/config/riscv/riscv.h
index 073b9e4..2bcabd0 100644
--- a/gcc/config/riscv/riscv.h
+++ b/gcc/config/riscv/riscv.h
@@ -191,7 +191,7 @@ ASM_MISA_SPEC
/* Allocation boundary (in *bits*) for the code of a function. */
#define FUNCTION_BOUNDARY \
- (((TARGET_RVC || TARGET_ZCA) && !TARGET_ZICFILP) ? 16 : 32)
+ (((TARGET_RVC || TARGET_ZCA) && !is_zicfilp_p ()) ? 16 : 32)
/* The smallest supported stack boundary the calling convention supports. */
#define STACK_BOUNDARY \
@@ -415,7 +415,7 @@ ASM_MISA_SPEC
/* Register in which static-chain is passed to a function. */
#define STATIC_CHAIN_REGNUM \
- ((TARGET_ZICFILP) ? (GP_TEMP_FIRST + 23) : (GP_TEMP_FIRST + 2))
+ ((is_zicfilp_p ()) ? (GP_TEMP_FIRST + 23) : (GP_TEMP_FIRST + 2))
/* Registers used as temporaries in prologue/epilogue code.
@@ -827,7 +827,7 @@ extern enum riscv_cc get_riscv_cc (const rtx use);
/* Trampolines are a block of code followed by two pointers. */
-#define TRAMPOLINE_CODE_SIZE ((TARGET_ZICFILP) ? 24 : 16)
+#define TRAMPOLINE_CODE_SIZE ((is_zicfilp_p ()) ? 24 : 16)
#define TRAMPOLINE_SIZE \
((Pmode == SImode) \
@@ -1196,6 +1196,8 @@ extern poly_int64 riscv_v_adjust_nunits (enum machine_mode, int);
extern poly_int64 riscv_v_adjust_nunits (machine_mode, bool, int, int);
extern poly_int64 riscv_v_adjust_precision (enum machine_mode, int);
extern poly_int64 riscv_v_adjust_bytesize (enum machine_mode, int);
+extern bool is_zicfiss_p ();
+extern bool is_zicfilp_p ();
extern bool need_shadow_stack_push_pop_p ();
/* The number of bits and bytes in a RVV vector. */
#define BITS_PER_RISCV_VECTOR (poly_uint16 (riscv_vector_chunks * riscv_bytes_per_vector_chunk * 8))
diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index a3fc3a1..c2a9de6 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -3711,11 +3711,11 @@
[(set (pc) (match_operand 0 "register_operand"))]
""
{
- if (TARGET_ZICFILP)
+ if (is_zicfilp_p ())
emit_insn (gen_set_lpl (Pmode, const0_rtx));
operands[0] = force_reg (Pmode, operands[0]);
- if (TARGET_ZICFILP)
+ if (is_zicfilp_p ())
emit_use (gen_rtx_REG (Pmode, T2_REGNUM));
if (Pmode == SImode)
@@ -3743,7 +3743,7 @@
gen_rtx_LABEL_REF (Pmode, operands[1]),
NULL_RTX, 0, OPTAB_DIRECT);
- if (TARGET_ZICFILP)
+ if (is_zicfilp_p ())
{
rtx t2 = RISCV_CALL_ADDRESS_LPAD (GET_MODE (operands[0]));
emit_move_insn (t2, operands[0]);
@@ -3766,7 +3766,7 @@
(define_insn "tablejump<mode>"
[(set (pc) (match_operand:GPR 0 "register_operand" "l"))
(use (label_ref (match_operand 1 "" "")))]
- "!TARGET_ZICFILP"
+ "!is_zicfilp_p ()"
"jr\t%0"
[(set_attr "type" "jalr")
(set_attr "mode" "none")])
@@ -3774,7 +3774,7 @@
(define_insn "tablejump_cfi<mode>"
[(set (pc) (reg:GPR T2_REGNUM))
(use (label_ref (match_operand 0 "")))]
- "TARGET_ZICFILP"
+ "is_zicfilp_p ()"
"jr\tt2"
[(set_attr "type" "jalr")
(set_attr "mode" "none")])
diff --git a/gcc/testsuite/c-c++-common/fcf-protection-1.c b/gcc/testsuite/c-c++-common/fcf-protection-1.c
index f59a8fb..cc30c92 100644
--- a/gcc/testsuite/c-c++-common/fcf-protection-1.c
+++ b/gcc/testsuite/c-c++-common/fcf-protection-1.c
@@ -1,3 +1,4 @@
/* { dg-do compile } */
/* { dg-options "-fcf-protection=full" } */
+/* { dg-skip-if "" { "riscv*-*-*" } } */
/* { dg-error "'-fcf-protection=full' is not supported for this target" "" { target { ! "i?86-*-* x86_64-*-*" } } 0 } */
diff --git a/gcc/testsuite/c-c++-common/fcf-protection-2.c b/gcc/testsuite/c-c++-common/fcf-protection-2.c
index 6105972..e318989 100644
--- a/gcc/testsuite/c-c++-common/fcf-protection-2.c
+++ b/gcc/testsuite/c-c++-common/fcf-protection-2.c
@@ -1,3 +1,4 @@
/* { dg-do compile } */
/* { dg-options "-fcf-protection=branch" } */
+/* { dg-skip-if "" { "riscv*-*-*" } } */
/* { dg-error "'-fcf-protection=branch' is not supported for this target" "" { target { ! "i?86-*-* x86_64-*-*" } } 0 } */
diff --git a/gcc/testsuite/c-c++-common/fcf-protection-3.c b/gcc/testsuite/c-c++-common/fcf-protection-3.c
index 257e944..dd60017 100644
--- a/gcc/testsuite/c-c++-common/fcf-protection-3.c
+++ b/gcc/testsuite/c-c++-common/fcf-protection-3.c
@@ -1,3 +1,4 @@
/* { dg-do compile } */
/* { dg-options "-fcf-protection=return" } */
+/* { dg-skip-if "" { "riscv*-*-*" } } */
/* { dg-error "'-fcf-protection=return' is not supported for this target" "" { target { ! "i?86-*-* x86_64-*-*" } } 0 } */
diff --git a/gcc/testsuite/c-c++-common/fcf-protection-4.c b/gcc/testsuite/c-c++-common/fcf-protection-4.c
index af4fc0b..2bde6e1 100644
--- a/gcc/testsuite/c-c++-common/fcf-protection-4.c
+++ b/gcc/testsuite/c-c++-common/fcf-protection-4.c
@@ -1,2 +1,3 @@
/* { dg-do compile } */
+/* { dg-skip-if "" { "riscv*-*-*" } } */
/* { dg-options "-fcf-protection=none" } */
diff --git a/gcc/testsuite/c-c++-common/fcf-protection-5.c b/gcc/testsuite/c-c++-common/fcf-protection-5.c
index dc317f8..8c675c5 100644
--- a/gcc/testsuite/c-c++-common/fcf-protection-5.c
+++ b/gcc/testsuite/c-c++-common/fcf-protection-5.c
@@ -1,3 +1,4 @@
/* { dg-do compile } */
/* { dg-options "-fcf-protection" } */
+/* { dg-skip-if "" { "riscv*-*-*" } } */
/* { dg-error "'-fcf-protection=full' is not supported for this target" "" { target { ! "i?86-*-* x86_64-*-*" } } 0 } */
diff --git a/gcc/testsuite/c-c++-common/fcf-protection-6.c b/gcc/testsuite/c-c++-common/fcf-protection-6.c
index 6105972..e318989 100644
--- a/gcc/testsuite/c-c++-common/fcf-protection-6.c
+++ b/gcc/testsuite/c-c++-common/fcf-protection-6.c
@@ -1,3 +1,4 @@
/* { dg-do compile } */
/* { dg-options "-fcf-protection=branch" } */
+/* { dg-skip-if "" { "riscv*-*-*" } } */
/* { dg-error "'-fcf-protection=branch' is not supported for this target" "" { target { ! "i?86-*-* x86_64-*-*" } } 0 } */
diff --git a/gcc/testsuite/c-c++-common/fcf-protection-7.c b/gcc/testsuite/c-c++-common/fcf-protection-7.c
index 257e944..dd60017 100644
--- a/gcc/testsuite/c-c++-common/fcf-protection-7.c
+++ b/gcc/testsuite/c-c++-common/fcf-protection-7.c
@@ -1,3 +1,4 @@
/* { dg-do compile } */
/* { dg-options "-fcf-protection=return" } */
+/* { dg-skip-if "" { "riscv*-*-*" } } */
/* { dg-error "'-fcf-protection=return' is not supported for this target" "" { target { ! "i?86-*-* x86_64-*-*" } } 0 } */
diff --git a/gcc/testsuite/gcc.target/riscv/interrupt-no-lpad.c b/gcc/testsuite/gcc.target/riscv/interrupt-no-lpad.c
index ff512b9..1290b37 100644
--- a/gcc/testsuite/gcc.target/riscv/interrupt-no-lpad.c
+++ b/gcc/testsuite/gcc.target/riscv/interrupt-no-lpad.c
@@ -1,5 +1,5 @@
/* { dg-do compile { target { riscv64*-*-* } } } */
-/* { dg-options "-march=rv64gc_zicfilp -mabi=lp64d" } */
+/* { dg-options "-march=rv64gc_zicfilp -mabi=lp64d -fcf-protection=branch" } */
void __attribute__ ((interrupt))
foo (void)
{
diff --git a/gcc/testsuite/gcc.target/riscv/ssp-1.c b/gcc/testsuite/gcc.target/riscv/ssp-1.c
index abf47ec..24e3010 100644
--- a/gcc/testsuite/gcc.target/riscv/ssp-1.c
+++ b/gcc/testsuite/gcc.target/riscv/ssp-1.c
@@ -1,5 +1,5 @@
/* { dg-do compile { target { riscv64*-*-* } } } */
-/* { dg-options "-O2 -march=rv64gc_zicfiss -mabi=lp64d" } */
+/* { dg-options "-O2 -march=rv64gc_zicfiss -mabi=lp64d -fcf-protection=return" } */
/* { dg-skip-if "" { *-*-* } { "-O0" } } */
struct ad {
void *ae;
diff --git a/gcc/testsuite/gcc.target/riscv/ssp-2.c b/gcc/testsuite/gcc.target/riscv/ssp-2.c
index 7c60983..9d3d6b2 100644
--- a/gcc/testsuite/gcc.target/riscv/ssp-2.c
+++ b/gcc/testsuite/gcc.target/riscv/ssp-2.c
@@ -1,5 +1,5 @@
/* { dg-do compile { target { riscv64*-*-* } } } */
-/* { dg-options "-O0 -march=rv64gc_zicfiss -mabi=lp64d" } */
+/* { dg-options "-O0 -march=rv64gc_zicfiss -mabi=lp64d -fcf-protection=return" } */
void __attribute__ ((interrupt))
foo (void)
diff --git a/gcc/testsuite/gcc.target/riscv/zicfilp-call.c b/gcc/testsuite/gcc.target/riscv/zicfilp-call.c
index 75c8b32..eb9e146 100644
--- a/gcc/testsuite/gcc.target/riscv/zicfilp-call.c
+++ b/gcc/testsuite/gcc.target/riscv/zicfilp-call.c
@@ -1,5 +1,5 @@
/* { dg-do compile { target { riscv64*-*-* } } } */
-/* { dg-options "-O2 -fPIE -march=rv64gc_zicfilp -mabi=lp64d" } */
+/* { dg-options "-O2 -fPIE -march=rv64gc_zicfilp -mabi=lp64d -fcf-protection=branch" } */
/* { dg-skip-if "" { *-*-* } { "-O0" } } */
extern void _dl_find_object_init (void);