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