gcc/ChangeLog:
        * gcc/config/riscv/riscv.cc
        (riscv_file_end_indicate_exec_stack): Add .note.gnu.property.
        * gcc/config/riscv/linux.h (TARGET_ASM_FILE_END): Define.

libgcc/ChangeLog:
        * libgcc/config/riscv/crti.S: Add lpad instructions.
        * libgcc/config/riscv/crtn.S: Likewise.
        * libgcc/config/riscv/save-restore.S: Likewise.
        * libgcc/config/riscv/riscv-asm.h: Add GNU_PROPERTY for ZICFILP,
          ZICFISS.

Co-Developed-by: Jesse Huang <jesse.hu...@sifive.com>
---
 gcc/config/riscv/riscv.cc          | 52 +++++++++++++++++++++-
 libgcc/config/riscv/crti.S         |  2 +
 libgcc/config/riscv/crtn.S         |  2 +
 libgcc/config/riscv/riscv-asm.h    | 69 +++++++++++++++++++++++++++++-
 libgcc/config/riscv/save-restore.S |  5 +++
 5 files changed, 128 insertions(+), 2 deletions(-)

diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 4afb0b95839..cb448aba9c0 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -10334,6 +10334,56 @@ riscv_file_start (void)
     riscv_emit_attribute ();
 }
 
+void
+riscv_file_end ()
+{
+  file_end_indicate_exec_stack ();
+  long GNU_PROPERTY_RISCV_FEATURE_1_AND  = 0;
+  unsigned long feature_1_and = 0;
+
+  if (TARGET_ZICFISS)
+    feature_1_and |= 0x1 << 0;
+
+  if (TARGET_ZICFILP)
+    feature_1_and |= 0x1 << 1;
+
+  if (feature_1_and)
+    {
+      /* Generate .note.gnu.property section.  */
+      switch_to_section (get_section (".note.gnu.property",
+                                     SECTION_NOTYPE, NULL));
+
+      /* The program property descriptor is aligned to 4 bytes in 32-bit
+        objects and 8 bytes in 64-bit objects.  */
+      unsigned p2align = TARGET_64BIT ? 3 : 2;
+
+      fprintf (asm_out_file, "\t.p2align\t%u\n", p2align);
+      /* name length.  */
+      fprintf (asm_out_file, "\t.long\t1f - 0f\n");
+      /* data length.  */
+      fprintf (asm_out_file, "\t.long\t5f - 2f\n");
+      /* note type.  */
+      fprintf (asm_out_file, "\t.long\t5\n");
+      fprintf (asm_out_file, "0:\n");
+      /* vendor name: "GNU".  */
+      fprintf (asm_out_file, "\t.asciz\t\"GNU\"\n");
+      fprintf (asm_out_file, "1:\n");
+
+      /* pr_type.  */
+      fprintf (asm_out_file, "\t.p2align\t3\n");
+      fprintf (asm_out_file, "2:\n");
+      fprintf (asm_out_file, "\t.long\t0xc0000000\n");
+      /* pr_datasz.  */
+      fprintf (asm_out_file, "\t.long\t4f - 3f\n");
+      fprintf (asm_out_file, "3:\n");
+      /* zicfiss, zicfilp.  */
+      fprintf (asm_out_file, "\t.long\t%x\n", feature_1_and);
+      fprintf (asm_out_file, "4:\n");
+      fprintf (asm_out_file, "\t.p2align\t%u\n", p2align);
+      fprintf (asm_out_file, "5:\n");
+    }
+}
+
 /* Implement TARGET_ASM_OUTPUT_MI_THUNK.  Generate rtl rather than asm text
    in order to avoid duplicating too much logic from elsewhere.  */
 
@@ -13975,7 +14025,7 @@ bool need_shadow_stack_push_pop_p ()
 #undef TARGET_ASM_FILE_START_FILE_DIRECTIVE
 #define TARGET_ASM_FILE_START_FILE_DIRECTIVE true
 #undef TARGET_ASM_FILE_END
-#define TARGET_ASM_FILE_END file_end_indicate_exec_stack
+#define TARGET_ASM_FILE_END riscv_file_end
 
 #undef TARGET_EXPAND_BUILTIN_VA_START
 #define TARGET_EXPAND_BUILTIN_VA_START riscv_va_start
diff --git a/libgcc/config/riscv/crti.S b/libgcc/config/riscv/crti.S
index 89bac706c63..3a67fd77156 100644
--- a/libgcc/config/riscv/crti.S
+++ b/libgcc/config/riscv/crti.S
@@ -1 +1,3 @@
 /* crti.S is empty because .init_array/.fini_array are used exclusively. */
+
+#include "riscv-asm.h"
diff --git a/libgcc/config/riscv/crtn.S b/libgcc/config/riscv/crtn.S
index ca6ee7b6fba..cb80782bb55 100644
--- a/libgcc/config/riscv/crtn.S
+++ b/libgcc/config/riscv/crtn.S
@@ -1 +1,3 @@
 /* crtn.S is empty because .init_array/.fini_array are used exclusively. */
+
+#include "riscv-asm.h"
diff --git a/libgcc/config/riscv/riscv-asm.h b/libgcc/config/riscv/riscv-asm.h
index b6dbeaedc20..73bddb3f9e7 100644
--- a/libgcc/config/riscv/riscv-asm.h
+++ b/libgcc/config/riscv/riscv-asm.h
@@ -23,9 +23,11 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If 
not, see
 #define FUNC_SIZE(X)   .size X,.-X
 
 #define FUNC_BEGIN(X)          \
+       .align 2;               \
        .globl X;               \
        FUNC_TYPE (X);          \
-X:
+X:                             \
+       LPAD
 
 #define FUNC_END(X)            \
        FUNC_SIZE(X)
@@ -39,3 +41,68 @@ X:
 #define HIDDEN_JUMPTARGET(X)   CONCAT1(__hidden_, X)
 #define HIDDEN_DEF(X)          FUNC_ALIAS(HIDDEN_JUMPTARGET(X), X);     \
                                .hidden HIDDEN_JUMPTARGET(X)
+
+/* GNU_PROPERTY_RISCV64_* macros from elf.h for use in asm code.  */
+#define FEATURE_1_AND 0xc0000000
+#define FEATURE_1_FCFI 1
+#define FEATURE_1_BCFI 2
+
+/* Add a NT_GNU_PROPERTY_TYPE_0 note.  */
+#if __riscv_xlen == 32
+#  define GNU_PROPERTY(type, value)    \
+    .section .note.gnu.property, "a";  \
+    .p2align 2;                                \
+    .word 4;                           \
+    .word 12;                          \
+    .word 5;                           \
+    .asciz "GNU";                      \
+    .word type;                                \
+    .word 4;                           \
+    .word value;                       \
+    .text
+#else
+#  define GNU_PROPERTY(type, value)    \
+    .section .note.gnu.property, "a";  \
+    .p2align 3;                                \
+    .word 4;                           \
+    .word 16;                          \
+    .word 5;                           \
+    .asciz "GNU";                      \
+    .word type;                                \
+    .word 4;                           \
+    .word value;                       \
+    .word 0;                           \
+    .text
+#endif
+
+/* Add GNU property note with the supported features to all asm code
+   where sysdep.h is included.  */
+#undef __VALUE_FOR_FEATURE_1_AND
+#if defined (__riscv_zicfilp) || defined (__riscv_zicfiss)
+#  if defined (__riscv_zicfilp)
+#    if defined (__riscv_zicfiss)
+#      define __VALUE_FOR_FEATURE_1_AND 0x3
+#    else
+#      define __VALUE_FOR_FEATURE_1_AND 0x1
+#    endif
+#  else
+#    if defined (__riscv_zicfiss)
+#      define __VALUE_FOR_FEATURE_1_AND 0x2
+#    else
+#      error "What?"
+#    endif
+#  endif
+#endif
+
+#if defined (__VALUE_FOR_FEATURE_1_AND)
+GNU_PROPERTY (FEATURE_1_AND, __VALUE_FOR_FEATURE_1_AND)
+#endif
+#undef __VALUE_FOR_FEATURE_1_AND
+
+#ifdef __riscv_zicfilp
+# define SET_LPAD   lui  t2, 0
+# define LPAD       lpad 0
+#else
+# define SET_LPAD
+# define LPAD
+#endif
diff --git a/libgcc/config/riscv/save-restore.S 
b/libgcc/config/riscv/save-restore.S
index ae8312d27db..fc654472a4c 100644
--- a/libgcc/config/riscv/save-restore.S
+++ b/libgcc/config/riscv/save-restore.S
@@ -137,6 +137,7 @@ FUNC_BEGIN (__riscv_save_2)
   # CFA info is not correct in next 2 instruction since t1's
   # value is depend on how may register really save.
   add sp, sp, t1
+  SET_LPAD
   jr t0
   .cfi_endproc
 FUNC_END (__riscv_save_12)
@@ -162,6 +163,7 @@ FUNC_BEGIN (__riscv_save_0)
   .cfi_offset 8, -16
   sd ra, 8(sp)
   .cfi_offset 1, -8
+  SET_LPAD
   jr t0
   .cfi_endproc
 FUNC_END (__riscv_save_1)
@@ -310,6 +312,7 @@ FUNC_BEGIN(__riscv_save_0)
   .cfi_offset 8, -8
   sw ra, 8(sp)
   .cfi_offset 1, -4
+  SET_LPAD
   jr t0
   .cfi_endproc
 FUNC_END(__riscv_save_2)
@@ -399,6 +402,7 @@ FUNC_BEGIN (__riscv_save_4)
   # CFA info is not correct in next 2 instruction since t1's
   # value is depend on how may register really save.
   sub sp, sp, t1
+  SET_LPAD
   jr t0
   .cfi_endproc
 FUNC_END (__riscv_save_12)
@@ -428,6 +432,7 @@ FUNC_BEGIN (__riscv_save_0)
   .cfi_offset 8, -8
   sw ra, 12(sp)
   .cfi_offset 1, -4
+  SET_LPAD
   jr t0
   .cfi_endproc
 FUNC_END (__riscv_save_3)
-- 
2.47.1

Reply via email to