https://gcc.gnu.org/g:59a869d7196132ae5257fcb068508561d3526c7d
commit r15-6988-g59a869d7196132ae5257fcb068508561d3526c7d Author: Monk Chiang <monk.chi...@sifive.com> Date: Fri Nov 15 18:18:36 2024 +0800 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. Diff: --- gcc/config/riscv/riscv-c.cc | 9 ++++ gcc/config/riscv/riscv-zicfilp.cc | 2 +- gcc/config/riscv/riscv.cc | 52 +++++++++++++++++----- gcc/config/riscv/riscv.h | 8 ++-- gcc/config/riscv/riscv.md | 10 ++--- gcc/testsuite/c-c++-common/fcf-protection-1.c | 1 + gcc/testsuite/c-c++-common/fcf-protection-2.c | 1 + gcc/testsuite/c-c++-common/fcf-protection-3.c | 1 + gcc/testsuite/c-c++-common/fcf-protection-4.c | 1 + gcc/testsuite/c-c++-common/fcf-protection-5.c | 1 + gcc/testsuite/c-c++-common/fcf-protection-6.c | 1 + gcc/testsuite/c-c++-common/fcf-protection-7.c | 1 + gcc/testsuite/gcc.target/riscv/interrupt-no-lpad.c | 2 +- gcc/testsuite/gcc.target/riscv/ssp-1.c | 2 +- gcc/testsuite/gcc.target/riscv/ssp-2.c | 2 +- gcc/testsuite/gcc.target/riscv/zicfilp-call.c | 2 +- 16 files changed, 72 insertions(+), 24 deletions(-) diff --git a/gcc/config/riscv/riscv-c.cc b/gcc/config/riscv/riscv-c.cc index e28d5574eeda..7912b1069f79 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 42b129920b3b..834d6e5c7783 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 37c3431a00a1..aa5cb8af682b 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 073b9e4f2bd2..2bcabd03517a 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 a3fc3a196ba0..c2a9de610526 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 f59a8fbdfdc9..cc30c921a164 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 61059725af66..e318989f290e 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 257e944c4a6b..dd60017dde06 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 af4fc0b28126..2bde6e1e7674 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 dc317f84b071..8c675c5f4832 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 61059725af66..e318989f290e 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 257e944c4a6b..dd60017dde06 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 ff512b98c616..1290b373f08d 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 abf47ec6442f..24e3010c3cc6 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 7c6098357e9d..9d3d6b27038d 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 75c8b32faa39..eb9e1468e7f2 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);