@@ -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
@@ -1 +1,3 @@
/* crti.S is empty because .init_array/.fini_array are used exclusively. */
+
+#include "riscv-asm.h"
@@ -1 +1,3 @@
/* crtn.S is empty because .init_array/.fini_array are used exclusively. */
+
+#include "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
@@ -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)