]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
RISC-V: Add -fcf-protection=[full|branch|return] to enable zicfiss, zicfilp.
authorMonk Chiang <monk.chiang@sifive.com>
Fri, 15 Nov 2024 10:18:36 +0000 (18:18 +0800)
committerMonk Chiang <monk.chiang@sifive.com>
Fri, 17 Jan 2025 02:55:07 +0000 (10:55 +0800)
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.

16 files changed:
gcc/config/riscv/riscv-c.cc
gcc/config/riscv/riscv-zicfilp.cc
gcc/config/riscv/riscv.cc
gcc/config/riscv/riscv.h
gcc/config/riscv/riscv.md
gcc/testsuite/c-c++-common/fcf-protection-1.c
gcc/testsuite/c-c++-common/fcf-protection-2.c
gcc/testsuite/c-c++-common/fcf-protection-3.c
gcc/testsuite/c-c++-common/fcf-protection-4.c
gcc/testsuite/c-c++-common/fcf-protection-5.c
gcc/testsuite/c-c++-common/fcf-protection-6.c
gcc/testsuite/c-c++-common/fcf-protection-7.c
gcc/testsuite/gcc.target/riscv/interrupt-no-lpad.c
gcc/testsuite/gcc.target/riscv/ssp-1.c
gcc/testsuite/gcc.target/riscv/ssp-2.c
gcc/testsuite/gcc.target/riscv/zicfilp-call.c

index e28d5574eedadf2519b23849c85bd42b8b0df933..7912b1069f7947c814e7bd46ea39bc1941fb4b9d 100644 (file)
@@ -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;
index 42b129920b3bfa4b175139781bde1987132a9f3e..834d6e5c7783d356488ab6a888d574a8e47af531 100644 (file)
@@ -150,7 +150,7 @@ public:
   /* opt_pass methods: */
   virtual bool gate (function *)
     {
-      return TARGET_ZICFILP;
+      return is_zicfilp_p ();
     }
 
   virtual unsigned int execute (function *)
index 37c3431a00a128e093e904d46c9ffb45cc39295f..aa5cb8af682b24f9cc27d57d814bb23bf9024824 100644 (file)
@@ -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.  */
index 073b9e4f2bd20456ab3fb3a19c71c9d283f76200..2bcabd03517a914ff9aebe51dcceb8f584c7beeb 100644 (file)
@@ -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))
index a3fc3a196ba00c92c3aad400b7b77e7f2f15b708..c2a9de610526777f16dafc9303689697815094de 100644 (file)
   [(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)
                                         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]);
 (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")])
 (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")])
index f59a8fbdfdc9b7063da1b2ddca9f0e709e6c1eba..cc30c921a164a3b09472cbc37294397757617222 100644 (file)
@@ -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 } */
index 61059725af66eedff19ccf994731baa6a952c930..e318989f290e80218b826ce10ccdc3a25d0fe837 100644 (file)
@@ -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 } */
index 257e944c4a6b15f808df5c11f430609abf15cb3a..dd60017dde069fb43574b7906b10703567f37cd2 100644 (file)
@@ -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 } */
index af4fc0b28126128ac717a3d946e276e353f62f68..2bde6e1e7674642f322fdab40f9beb0f7c7dc6cf 100644 (file)
@@ -1,2 +1,3 @@
 /* { dg-do compile } */
+/* { dg-skip-if "" { "riscv*-*-*" } } */
 /* { dg-options "-fcf-protection=none" } */
index dc317f84b0713c0d27f37c45c47388187185b7f3..8c675c5f4832122f1c735fdc3204f4164d761e0d 100644 (file)
@@ -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 } */
index 61059725af66eedff19ccf994731baa6a952c930..e318989f290e80218b826ce10ccdc3a25d0fe837 100644 (file)
@@ -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 } */
index 257e944c4a6b15f808df5c11f430609abf15cb3a..dd60017dde069fb43574b7906b10703567f37cd2 100644 (file)
@@ -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 } */
index ff512b98c6165e815f21abb1905844c79f014f74..1290b373f08daf98eb10d5254e794bc7cd21fc9f 100644 (file)
@@ -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)
 {
index abf47ec6442f1c7d8b993949f4071f38e1125657..24e3010c3cc653454862e66bdea0b3386d67a69c 100644 (file)
@@ -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;
index 7c6098357e9ddb02db732120cfa18ec9dc49d62c..9d3d6b27038dd0f67fc5fcbc4cf5164e4b67af12 100644 (file)
@@ -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)
index 75c8b32faa3926bdca0c94406fd98a1dae429cb5..eb9e1468e7f21349b0a231616c8171a70ca06afc 100644 (file)
@@ -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);