From patchwork Wed Jan 15 07:53:44 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Monk Chiang X-Patchwork-Id: 104809 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id D57623854820 for ; Wed, 15 Jan 2025 07:57:19 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org D57623854820 Authentication-Results: sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=sifive.com header.i=@sifive.com header.a=rsa-sha256 header.s=google header.b=au6lRG0F X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-pl1-x629.google.com (mail-pl1-x629.google.com [IPv6:2607:f8b0:4864:20::629]) by sourceware.org (Postfix) with ESMTPS id 212B5385C6CE for ; Wed, 15 Jan 2025 07:53:55 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 212B5385C6CE Authentication-Results: sourceware.org; dmarc=pass (p=reject dis=none) header.from=sifive.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=sifive.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 212B5385C6CE Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::629 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1736927635; cv=none; b=mtCbqWAHcQPD8hQEFoqMiNbHMO42Mrm+fUwlXIJ2Bao0kqpGONw7ZWvBQfpib0QhpAlg+ifF80Ju+dTVtSFXVA5bzrjSxoBxOY8Vi/1+BYbj/pj5PkzX8bIXuxmIX/D/b/ElKI659/7p/iYTvrD0ckyC4o70uTl7tql23apCVFI= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1736927635; c=relaxed/simple; bh=88LcRkjzZtHD+GPvtRICiGQ3Cz6jD3BagtkbFhcIDEo=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=CobI2lJ28M2biVVlspDUFc5yb4o/YPctCXPv8lr2nCnI65QrEP0fng+AzMV9lmplaKfv4X5BtTYWp2UjX10X8h6VcY5B9gmT3GWbOXedoq/+GymiUGAo+IplAUmTvztAkBiJuPFLGLeUGyrsL/vWakPq+cQpWLIM7uQAIdY4ezE= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 212B5385C6CE Received: by mail-pl1-x629.google.com with SMTP id d9443c01a7336-21661be2c2dso112695625ad.1 for ; Tue, 14 Jan 2025 23:53:55 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sifive.com; s=google; t=1736927634; x=1737532434; darn=gcc.gnu.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=b0b5rFemfHZvaaJwDDr4QAk0INqsgPXH3g4i2dtq1eE=; b=au6lRG0FlUgDJ0zlv60si8mu53J9fiGXx2YqJdmhxg8pkqBZXPmQiTzImp1+8iT9zS OQ0kD4VJWVUvPT7Sh675dCscIs9+zZ9OJFlYuJZLYi9fMc7HZHYiVTMm8z/cZf954NMa v+KFkSSb6sxQns823JU3ocPnrq+KX/uW1CpFVPY+YD81sFAp+1OiMGXrPRVXL3mLLM+p q8kiznzMtpbykb784IQU928UKiPjkMGYuNi3Ekuh9jJ7cB+8i3C6KWUfeqYKFRPhlAb8 ibr8dMsRxl8KEXY9YLmaIEZ+MkHtS5dbu3UVJn9clEj9Ocy8WYy0XOtjYdp9QLP7Tli8 IuwA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1736927634; x=1737532434; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=b0b5rFemfHZvaaJwDDr4QAk0INqsgPXH3g4i2dtq1eE=; b=TeLn/Qvyu4/NtMzektjsNge/VaqzKWR7hUzsUpDEy778sY+QVttOyCOWkFo3O4NxkD mFP25IqKC4qd8DpQ7a1Lpkb/g/Lo2ZswlubGrxkuB5BhVt+mDEeI5C50aRY/azglqOFj e85e4Ms+3APo2YlLhwmhxwxfhnjXqiXYKBZfdWLqIUYg9RhCwJxZ+pb3GlTpa3sbVJ1S qAagpodJbuiiZ1utHaHFPL15/sFtGjWvUS//CioEFSMQvImSxfXcvErAac/qb2eYfdQ1 yUiTjdWE/nw6ewPzHSJe2+2ZPTCzUjA7u6SLLCCVGlZ1KaTAwtArnnoN9MoB08Rmm0CZ oGZA== X-Gm-Message-State: AOJu0YxNcozab6ncUhMKGyTcqeT9x/x9LAVhiklIqbmQ9tsMB9OOYhOt LgvRbYIOWaNIbnclSebpJE+/tslbK3ufObNNXoUbccF8yRkbQBQfJQQy/bkFfh87sU9eTWU/zdX /WKwQmnLdPPU2u1T0rmCAeepOw9kBdL/cMXCo1x/xas+cgmzGxwhZ/xoinKxNAr770BvdY3CGkq RW4x7S7eo8btPuEaGRf7nDJ//EyUGnZ1cFRMfDRPpeqA== X-Gm-Gg: ASbGnctieDc0k5g2JBt+zML3/GqDZUNvkm5EQ5Y7bc12g0F7QKtZ9CMR2fPgFR35ZoH ZRP0gqoZ8x30mzOmoEkPxA58Bc+7+RxAqmXuP8+C145z4BM2fBeP7iMgP5ufmEQ8XhCBkxMt1CB maHwV7cwuYQ2sKIQ4tQ9cdkTktmKaV/EnrpSxHIArK0KxYH/Rljy+8Lz9rRBND13KxYgxF2Lm75 kJxiPrLQS3lY4rVcEYF3PLLk0RfcGFLGLaHqdBYO7an0eoGDX2wwb0arU6Q+gvlgCZeZVnGTZ6O g6IfKfX0 X-Google-Smtp-Source: AGHT+IH7wPJLRo+OMZox6a3AEsfM1p8Tm/WZ/3bDr1PZK33vkSNfAj/teC6kJn77QpGyXd29xLdw4Q== X-Received: by 2002:a17:90b:5146:b0:2ee:bbe0:98cd with SMTP id 98e67ed59e1d1-2f548e9a547mr41882286a91.7.1736927633651; Tue, 14 Jan 2025 23:53:53 -0800 (PST) Received: from hsinchu02.internal.sifive.com ([210.176.154.34]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2f72c19a5d4sm839877a91.17.2025.01.14.23.53.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 14 Jan 2025 23:53:53 -0800 (PST) From: Monk Chiang To: gcc-patches@gcc.gnu.org, kito@gcc.gnu.org Cc: Monk Chiang , Greg McGary Subject: [PATCH v3 1/4] RISC-V: Add Zicfiss ISA extension. Date: Wed, 15 Jan 2025 15:53:44 +0800 Message-ID: <20250115075347.61344-1-monk.chiang@sifive.com> X-Mailer: git-send-email 2.47.1 MIME-Version: 1.0 X-Spam-Status: No, score=-11.8 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, KAM_STOCKGEN, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP, URIBL_BLACK autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces~patchwork=sourceware.org@gcc.gnu.org This patch is implemented according to the RISC-V CFI specification. It supports the generation of shadow stack instructions in the prologue, epilogue, non-local gotos, and unwinding. RISC-V CFI SPEC: https://github.com/riscv/riscv-cfi gcc/ChangeLog: * common/config/riscv/riscv-common.cc: Add ZICFISS ISA string. * gcc/config/riscv/predicates.md: New predicate x1x5_operand. * gcc/config/riscv/riscv.cc (riscv_expand_prologue): Insert shadow stack instructions. (riscv_expand_epilogue): Likewise. (riscv_for_each_saved_reg): Assign t0 or ra register for sspopchk instruction. (need_shadow_stack_push_pop_p): New function. Omit shadow stack operation on leaf function. * gcc/config/riscv/riscv.h (need_shadow_stack_push_pop_p): Define. * gcc/config/riscv/riscv.md: Add shadow stack patterns. (save_stack_nonlocal): Add shadow stack instructions for setjump. (restore_stack_nonlocal): Add shadow stack instructions for longjump. libgcc/ChangeLog: * gcc/config/riscv/riscv.opt (TARGET_ZICFISS): Define. * libgcc/config/riscv/linux-unwind.h: Include shadow-stack-unwind.h. * libgcc/config/riscv/shadow-stack-unwind.h (_Unwind_Frames_Extra): Define. (_Unwind_Frames_Increment): Define. gcc/testsuite/ChangeLog: * gcc/testsuite/gcc.target/riscv/ssp-1.c: New test. * gcc/testsuite/gcc.target/riscv/ssp-2.c: New test. Co-Developed-by: Greg McGary --- gcc/common/config/riscv/riscv-common.cc | 7 ++ gcc/config/riscv/predicates.md | 6 ++ gcc/config/riscv/riscv.cc | 58 ++++++++-- gcc/config/riscv/riscv.h | 1 + gcc/config/riscv/riscv.md | 125 +++++++++++++++++++++- gcc/config/riscv/riscv.opt | 2 + gcc/testsuite/gcc.target/riscv/ssp-1.c | 41 +++++++ gcc/testsuite/gcc.target/riscv/ssp-2.c | 10 ++ libgcc/config/riscv/linux-unwind.h | 5 + libgcc/config/riscv/shadow-stack-unwind.h | 74 +++++++++++++ 10 files changed, 320 insertions(+), 9 deletions(-) create mode 100644 gcc/testsuite/gcc.target/riscv/ssp-1.c create mode 100644 gcc/testsuite/gcc.target/riscv/ssp-2.c create mode 100644 libgcc/config/riscv/shadow-stack-unwind.h diff --git a/gcc/common/config/riscv/riscv-common.cc b/gcc/common/config/riscv/riscv-common.cc index bfc8aa559c5..8e8b6107a6d 100644 --- a/gcc/common/config/riscv/riscv-common.cc +++ b/gcc/common/config/riscv/riscv-common.cc @@ -111,6 +111,9 @@ static const riscv_implied_info_t riscv_implied_info[] = {"zfinx", "zicsr"}, {"zdinx", "zicsr"}, + {"zicfiss", "zicsr"}, + {"zicfiss", "zimop"}, + {"zk", "zkn"}, {"zk", "zkr"}, {"zk", "zkt"}, @@ -325,6 +328,8 @@ static const struct riscv_ext_version riscv_ext_version_table[] = {"zicclsm", ISA_SPEC_CLASS_NONE, 1, 0}, {"ziccrse", ISA_SPEC_CLASS_NONE, 1, 0}, + {"zicfiss", ISA_SPEC_CLASS_NONE, 1, 0}, + {"zimop", ISA_SPEC_CLASS_NONE, 1, 0}, {"zcmop", ISA_SPEC_CLASS_NONE, 1, 0}, @@ -1647,6 +1652,8 @@ static const riscv_ext_flag_table_t riscv_ext_flag_table[] = RISCV_EXT_FLAG_ENTRY ("zicbop", x_riscv_zicmo_subext, MASK_ZICBOP), RISCV_EXT_FLAG_ENTRY ("zic64b", x_riscv_zicmo_subext, MASK_ZIC64B), + RISCV_EXT_FLAG_ENTRY ("zicfiss", x_riscv_zi_subext, MASK_ZICFISS), + RISCV_EXT_FLAG_ENTRY ("zimop", x_riscv_mop_subext, MASK_ZIMOP), RISCV_EXT_FLAG_ENTRY ("zcmop", x_riscv_mop_subext, MASK_ZCMOP), diff --git a/gcc/config/riscv/predicates.md b/gcc/config/riscv/predicates.md index cda7502a62a..1f67d30be9d 100644 --- a/gcc/config/riscv/predicates.md +++ b/gcc/config/riscv/predicates.md @@ -679,3 +679,9 @@ return (riscv_symbolic_constant_p (op, &type) && type == SYMBOL_PCREL); }) + +;; Shadow stack operands only allow x1, x5 registers +(define_predicate "x1x5_operand" + (and (match_operand 0 "register_operand") + (match_test "REGNO (op) == RETURN_ADDR_REGNUM + || REGNO (op) == T0_REGNUM"))) diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index 65e09842fde..cd37b492183 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -7496,6 +7496,9 @@ riscv_save_reg_p (unsigned int regno) if (regno == GP_REGNUM || regno == THREAD_POINTER_REGNUM) return false; + if (regno == RETURN_ADDR_REGNUM && TARGET_ZICFISS) + return true; + /* We must save every register used in this function. If this is not a leaf function, then we must save all temporary registers. */ if (df_regs_ever_live_p (regno) @@ -8049,7 +8052,7 @@ riscv_is_eh_return_data_register (unsigned int regno) static void riscv_for_each_saved_reg (poly_int64 sp_offset, riscv_save_restore_fn fn, - bool epilogue, bool maybe_eh_return) + bool epilogue, bool maybe_eh_return, bool sibcall_p) { HOST_WIDE_INT offset, first_fp_offset; unsigned int regno, num_masked_fp = 0; @@ -8135,7 +8138,14 @@ riscv_for_each_saved_reg (poly_int64 sp_offset, riscv_save_restore_fn fn, } } - riscv_save_restore_reg (word_mode, regno, offset, fn); + if (need_shadow_stack_push_pop_p () && epilogue && !sibcall_p + && !(maybe_eh_return && crtl->calls_eh_return) + && (regno == RETURN_ADDR_REGNUM) + && !cfun->machine->interrupt_handler_p) + riscv_save_restore_reg (word_mode, RISCV_PROLOGUE_TEMP_REGNUM, + offset, fn); + else + riscv_save_restore_reg (word_mode, regno, offset, fn); } /* This loop must iterate over the same space as its companion in @@ -8729,6 +8739,9 @@ riscv_expand_prologue (void) if (cfun->machine->naked_p) return; + if (need_shadow_stack_push_pop_p ()) + emit_insn (gen_sspush (Pmode, gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM))); + /* prefer multi-push to save-restore libcall. */ if (riscv_use_multi_push (frame)) { @@ -8772,7 +8785,7 @@ riscv_expand_prologue (void) = get_multi_push_fpr_mask (multi_push_additional / UNITS_PER_WORD); frame->fmask &= mask_fprs_push; riscv_for_each_saved_reg (remaining_size, riscv_save_reg, false, - false); + false, false); frame->fmask = fmask & ~mask_fprs_push; /* mask for the rest FPRs. */ } } @@ -8823,7 +8836,8 @@ riscv_expand_prologue (void) GEN_INT (-step1)); RTX_FRAME_RELATED_P (emit_insn (insn)) = 1; } - riscv_for_each_saved_reg (remaining_size, riscv_save_reg, false, false); + riscv_for_each_saved_reg (remaining_size, riscv_save_reg, + false, false, false); } /* Undo the above fib. */ @@ -8985,6 +8999,7 @@ riscv_expand_epilogue (int style) = use_multi_pop ? frame->multi_push_adj_base + frame->multi_push_adj_addi : 0; rtx ra = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM); + rtx t0 = gen_rtx_REG (Pmode, RISCV_PROLOGUE_TEMP_REGNUM); unsigned th_int_mask = 0; rtx insn; @@ -9194,7 +9209,8 @@ riscv_expand_epilogue (int style) riscv_for_each_saved_v_reg (step2, riscv_restore_reg, false); riscv_for_each_saved_reg (frame->total_size - step2 - libcall_size - multipop_size, - riscv_restore_reg, true, style == EXCEPTION_RETURN); + riscv_restore_reg, true, style == EXCEPTION_RETURN, + style == SIBCALL_RETURN); if (th_int_mask && TH_INT_INTERRUPT (cfun)) { @@ -9234,7 +9250,8 @@ riscv_expand_epilogue (int style) riscv_for_each_saved_reg (frame->total_size - libcall_size - multipop_size, riscv_restore_reg, true, - style == EXCEPTION_RETURN); + style == EXCEPTION_RETURN, false); + /* Undo the above fib. */ frame->mask = mask; frame->fmask = fmask; @@ -9259,6 +9276,17 @@ riscv_expand_epilogue (int style) emit_insn (gen_add3_insn (stack_pointer_rtx, stack_pointer_rtx, EH_RETURN_STACKADJ_RTX)); + if (need_shadow_stack_push_pop_p () + && !((style == EXCEPTION_RETURN) && crtl->calls_eh_return)) + { + if (BITSET_P (cfun->machine->frame.mask, RETURN_ADDR_REGNUM) + && style != SIBCALL_RETURN + && !cfun->machine->interrupt_handler_p) + emit_insn (gen_sspopchk (Pmode, t0)); + else + emit_insn (gen_sspopchk (Pmode, ra)); + } + /* Return from interrupt. */ if (cfun->machine->interrupt_handler_p) { @@ -9276,7 +9304,15 @@ riscv_expand_epilogue (int style) emit_jump_insn (gen_riscv_uret ()); } else if (style != SIBCALL_RETURN) - emit_jump_insn (gen_simple_return_internal (ra)); + { + if (need_shadow_stack_push_pop_p () + && !((style == EXCEPTION_RETURN) && crtl->calls_eh_return) + && BITSET_P (cfun->machine->frame.mask, RETURN_ADDR_REGNUM) + && !cfun->machine->interrupt_handler_p) + emit_jump_insn (gen_simple_return_internal (t0)); + else + emit_jump_insn (gen_simple_return_internal (ra)); + } } /* Implement EPILOGUE_USES. */ @@ -9473,7 +9509,8 @@ bool riscv_can_use_return_insn (void) { return (reload_completed && known_eq (cfun->machine->frame.total_size, 0) - && ! cfun->machine->interrupt_handler_p); + && ! cfun->machine->interrupt_handler_p + && ! need_shadow_stack_push_pop_p ()); } /* Given that there exists at least one variable that is set (produced) @@ -13786,6 +13823,11 @@ expand_reversed_crc_using_clmul (scalar_mode crc_mode, scalar_mode data_mode, riscv_emit_move (operands[0], gen_lowpart (crc_mode, a0)); } +bool need_shadow_stack_push_pop_p () +{ + return TARGET_ZICFISS && riscv_save_return_addr_reg_p (); +} + /* Initialize the GCC target structure. */ #undef TARGET_ASM_ALIGNED_HI_OP #define TARGET_ASM_ALIGNED_HI_OP "\t.half\t" diff --git a/gcc/config/riscv/riscv.h b/gcc/config/riscv/riscv.h index 4ff883af16b..93e88fe885d 100644 --- a/gcc/config/riscv/riscv.h +++ b/gcc/config/riscv/riscv.h @@ -1189,6 +1189,7 @@ 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 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)) #define BYTES_PER_RISCV_VECTOR (poly_uint16 (riscv_vector_chunks * riscv_bytes_per_vector_chunk)) diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md index 0922cab4402..21094395184 100644 --- a/gcc/config/riscv/riscv.md +++ b/gcc/config/riscv/riscv.md @@ -99,6 +99,12 @@ ;; CRC unspecs UNSPEC_CRC UNSPEC_CRC_REV + + ;; ZICFISS + UNSPECV_SSPUSH + UNSPECV_SSPOPCHK + UNSPECV_SSRDP + UNSPECV_SSP ]) (define_c_enum "unspecv" [ @@ -4116,6 +4122,30 @@ (set_attr "length" "0")] ) +(define_expand "save_stack_nonlocal" + [(set (match_operand 0 "memory_operand") + (match_operand 1 "register_operand"))] + "" +{ + rtx stack_slot; + + if (need_shadow_stack_push_pop_p ()) + { + /* Copy shadow stack pointer to the first slot + and stack pointer to the second slot. */ + rtx ssp_slot = adjust_address (operands[0], word_mode, 0); + stack_slot = adjust_address (operands[0], Pmode, UNITS_PER_WORD); + + rtx reg_ssp = force_reg (word_mode, const0_rtx); + emit_insn (gen_ssrdp (word_mode, reg_ssp)); + emit_move_insn (ssp_slot, reg_ssp); + } + else + stack_slot = adjust_address (operands[0], Pmode, 0); + emit_move_insn (stack_slot, operands[1]); + DONE; +}) + ;; This fixes a failure with gcc.c-torture/execute/pr64242.c at -O2 for a ;; 32-bit target when using -mtune=sifive-7-series. The first sched pass ;; runs before register elimination, and we have a non-obvious dependency @@ -4126,7 +4156,70 @@ (match_operand 1 "memory_operand")] "" { - emit_move_insn (operands[0], operands[1]); + rtx stack_slot; + + if (need_shadow_stack_push_pop_p ()) + { + rtx t0 = gen_rtx_REG (Pmode, RISCV_PROLOGUE_TEMP_REGNUM); + /* Restore shadow stack pointer from the first slot + and stack pointer from the second slot. */ + rtx ssp_slot = adjust_address (operands[1], word_mode, 0); + stack_slot = adjust_address (operands[1], Pmode, UNITS_PER_WORD); + + /* Get the current shadow stack pointer. */ + rtx cur_ssp = force_reg (word_mode, const0_rtx); + emit_insn (gen_ssrdp (word_mode, cur_ssp)); + + /* Compare and jump over adjustment code. */ + rtx noadj_label = gen_label_rtx (); + emit_cmp_and_jump_insns (cur_ssp, const0_rtx, EQ, NULL_RTX, + word_mode, 1, noadj_label); + + rtx loop_label = gen_label_rtx (); + emit_label (loop_label); + LABEL_NUSES (loop_label) = 1; + + /* Check if current ssp less than jump buffer ssp, + so no loop is needed. */ + emit_cmp_and_jump_insns (ssp_slot, cur_ssp, LE, NULL_RTX, + ptr_mode, 1, noadj_label); + + /* Advance by a maximum of 4K at a time to avoid unwinding + past bounds of the shadow stack. */ + rtx reg_4096 = force_reg (word_mode, GEN_INT (4096)); + rtx cmp_ssp = gen_reg_rtx (word_mode); + cmp_ssp = expand_simple_binop (ptr_mode, MINUS, + ssp_slot, cur_ssp, + cmp_ssp, 1, OPTAB_DIRECT); + + /* Update curr_ssp from jump buffer ssp. */ + emit_move_insn (cur_ssp, ssp_slot); + emit_insn (gen_write_ssp (word_mode, cur_ssp)); + emit_jump_insn (gen_jump (loop_label)); + emit_barrier (); + + /* Adjust the ssp in a loop. */ + rtx cmp_4k_label = gen_label_rtx (); + emit_label (cmp_4k_label); + LABEL_NUSES (cmp_4k_label) = 1; + + /* Add 4k for curr_ssp. */ + cur_ssp = expand_simple_binop (ptr_mode, PLUS, + cur_ssp, reg_4096, + cur_ssp, 1, OPTAB_DIRECT); + emit_insn (gen_write_ssp (word_mode, cur_ssp)); + emit_insn (gen_sspush (Pmode, t0)); + emit_insn (gen_sspopchk (Pmode, t0)); + emit_jump_insn (gen_jump (loop_label)); + emit_barrier (); + + emit_label (noadj_label); + LABEL_NUSES (noadj_label) = 1; + } + else + stack_slot = adjust_address (operands[1], Pmode, 0); + + emit_move_insn (operands[0], stack_slot); /* Prevent the following hard fp restore from being moved before the move insn above which uses a copy of the soft fp reg. */ emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx)); @@ -4594,6 +4687,36 @@ }" [(set_attr "type" "arith")]) +;; Shadow stack + +(define_insn "@sspush" + [(unspec_volatile [(match_operand:P 0 "x1x5_operand" "r")] UNSPECV_SSPUSH)] + "TARGET_ZICFISS" + "sspush\t%0" + [(set_attr "type" "arith") + (set_attr "mode" "")]) + +(define_insn "@sspopchk" + [(unspec_volatile [(match_operand:P 0 "x1x5_operand" "r")] UNSPECV_SSPOPCHK)] + "TARGET_ZICFISS" + "sspopchk\t%0" + [(set_attr "type" "arith") + (set_attr "mode" "")]) + +(define_insn "@ssrdp" + [(set (match_operand:P 0 "register_operand" "=r") + (unspec_volatile [(const_int 0)] UNSPECV_SSRDP))] + "TARGET_ZICFISS" + "ssrdp\t%0" + [(set_attr "type" "arith") + (set_attr "mode" "")]) + +(define_insn "@write_ssp" + [(unspec_volatile [(match_operand:P 0 "register_operand" "r")] UNSPECV_SSP)] + "TARGET_ZICFISS" + "csrw\tssp, %0" + [(set_attr "type" "arith") + (set_attr "mode" "")]) (include "bitmanip.md") (include "crypto.md") diff --git a/gcc/config/riscv/riscv.opt b/gcc/config/riscv/riscv.opt index 88fec1c8280..4a43bfd7bc6 100644 --- a/gcc/config/riscv/riscv.opt +++ b/gcc/config/riscv/riscv.opt @@ -253,6 +253,8 @@ Mask(ZICCLSM) Var(riscv_zi_subext) Mask(ZICCRSE) Var(riscv_zi_subext) +Mask(ZICFISS) Var(riscv_zi_subext) + TargetVariable int riscv_za_subext diff --git a/gcc/testsuite/gcc.target/riscv/ssp-1.c b/gcc/testsuite/gcc.target/riscv/ssp-1.c new file mode 100644 index 00000000000..abf47ec6442 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/ssp-1.c @@ -0,0 +1,41 @@ +/* { dg-do compile { target { riscv64*-*-* } } } */ +/* { dg-options "-O2 -march=rv64gc_zicfiss -mabi=lp64d" } */ +/* { dg-skip-if "" { *-*-* } { "-O0" } } */ +struct ad { + void *ae; +}; +struct af { + union { + int *ai; + int *aj; + struct ad *ak; + } u; + struct { + struct { + long al : 1; + long am : 1; + long : 21; + } b; + long i; + } s; +}; +void fdes (struct af *, void *, long *); + +void foo (struct af *bv, long *bw) { + bw[0] = bw[1] = 0; + if (bv->s.b.al) + fdes (bv, bv->u.ak->ae, bw); + else if (bv->s.b.am) { + int **p = (int**)bv->u.aj; + for (; *p; ++p) + fdes (bv, *p, bw); + } else + fdes (bv, bv->u.ai, bw); +} + +/* { dg-final { scan-assembler-times "ld\tt0" 1 } } */ +/* { dg-final { scan-assembler-times "sspopchk\tt0" 1 } } */ +/* { dg-final { scan-assembler-times "jr\tt0" 1 } } */ +/* { dg-final { scan-assembler-times "ld\tra" 2 } } */ +/* { dg-final { scan-assembler-times "sspopchk\tra" 2 } } */ +/* { dg-final { scan-assembler-times "tail" 2 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/ssp-2.c b/gcc/testsuite/gcc.target/riscv/ssp-2.c new file mode 100644 index 00000000000..7c6098357e9 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/ssp-2.c @@ -0,0 +1,10 @@ +/* { dg-do compile { target { riscv64*-*-* } } } */ +/* { dg-options "-O0 -march=rv64gc_zicfiss -mabi=lp64d" } */ + +void __attribute__ ((interrupt)) +foo (void) +{ +} +/* { dg-final { scan-assembler-times "sd\tra" 1 } } */ +/* { dg-final { scan-assembler-times "ld\tra" 1 } } */ +/* { dg-final { scan-assembler-times "sspopchk\tra" 1 } } */ diff --git a/libgcc/config/riscv/linux-unwind.h b/libgcc/config/riscv/linux-unwind.h index 40c8f51d6fc..db755cdc6a8 100644 --- a/libgcc/config/riscv/linux-unwind.h +++ b/libgcc/config/riscv/linux-unwind.h @@ -19,6 +19,11 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see . */ +/* Unwind shadow stack. */ +#if defined(__riscv_zicfiss) +# include "config/riscv/shadow-stack-unwind.h" +#endif + #ifndef inhibit_libc #include diff --git a/libgcc/config/riscv/shadow-stack-unwind.h b/libgcc/config/riscv/shadow-stack-unwind.h new file mode 100644 index 00000000000..c595ac103bc --- /dev/null +++ b/libgcc/config/riscv/shadow-stack-unwind.h @@ -0,0 +1,74 @@ +/* _Unwind_Frames_Extra with shadow stack. + Copyright (C) 2016-2024 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +. */ + +#define LIBGCC2_UNITS_PER_WORD (__riscv_xlen / 8) + +/* Unwind the shadow stack for EH. */ +#undef _Unwind_Frames_Extra +#define _Unwind_Frames_Extra(x) \ + do \ + { \ + _Unwind_Word ssp = 0; \ + asm volatile ("ssrdp %0" : "=r"(ssp)); \ + if (ssp != 0) \ + { \ + _Unwind_Word tmp = (x); \ + tmp = tmp * LIBGCC2_UNITS_PER_WORD; \ + while (tmp > 4096) \ + { \ + ssp += 4096; \ + tmp -= 4096; \ + asm volatile ("csrw ssp, %0" :: "r"(ssp)); \ + asm volatile ("sspush x5\n" \ + "sspopchk x5" : : : "x5"); \ + } \ + \ + if (tmp > 0) \ + { \ + ssp += tmp; \ + asm volatile ("csrw ssp, %0" :: "r"(ssp)); \ + } \ + } \ + } \ + while (0) + +#undef _Unwind_Frames_Increment +#define _Unwind_Frames_Increment(exc, context, frames) \ + { \ + frames++; \ + if (exc->exception_class != 0 \ + && _Unwind_GetIP (context) != 0 \ + && !_Unwind_IsSignalFrame (context)) \ + { \ + _Unwind_Word ssp; \ + asm volatile ("ssrdp %0" : "=r"(ssp)); \ + if (ssp != 0) \ + { \ + ssp += LIBGCC2_UNITS_PER_WORD * frames; \ + _Unwind_Word ra = *(_Unwind_Word *) ssp; \ + if (ra != _Unwind_GetIP (context)) \ + return _URC_FATAL_PHASE2_ERROR; \ + } \ + } \ + } From patchwork Wed Jan 15 07:53:45 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Monk Chiang X-Patchwork-Id: 104808 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id C25E2385DC00 for ; Wed, 15 Jan 2025 07:56:36 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org C25E2385DC00 Authentication-Results: sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=sifive.com header.i=@sifive.com header.a=rsa-sha256 header.s=google header.b=ZrzhKSAA X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-pl1-x629.google.com (mail-pl1-x629.google.com [IPv6:2607:f8b0:4864:20::629]) by sourceware.org (Postfix) with ESMTPS id E667D385481F for ; Wed, 15 Jan 2025 07:53:58 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org E667D385481F Authentication-Results: sourceware.org; dmarc=pass (p=reject dis=none) header.from=sifive.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=sifive.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org E667D385481F Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::629 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1736927639; cv=none; b=OGhTHQ9+Rn6PFV26utcADHASEkuBvzX2eXHPpMVSsjMsh/h1vnteD98GDNQFVTNyyKaNnDhEWTEqRZXThWrFQ8YM7AjOrH5ivgchT+2+SarlGgfxMNUHWTse4q6vYRFURgNQPl7bw7n+GnEnRxZUnm/85tfoUGvLaPqqs7Jzldk= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1736927639; c=relaxed/simple; bh=TDN8QX72GlfqJrDPbm5mkSpkoDYChS+Z5Cbujh979/Y=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=XW//j7xyb2+n01Wx6kqgyRiVoHvvDFiQla3ijYzQIXlUPhL4/VEnCCLqIFUlHjJyjT2aFP6gIw2/28zIzWNEBe2/Cgi2cXIEaAKNR69s4iB/86tmpRVi4xoM3m4cNAHo2MH8ablIU1ZM4HHVtmmkBZabcxy6yy75j+0oiYGw154= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org E667D385481F Received: by mail-pl1-x629.google.com with SMTP id d9443c01a7336-216634dd574so74869715ad.2 for ; Tue, 14 Jan 2025 23:53:58 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sifive.com; s=google; t=1736927637; x=1737532437; darn=gcc.gnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=F3fdHLVK61x8yyL/yphNE89C1K+GboFONSiIwYFJpPs=; b=ZrzhKSAAwy0tEGD+ot4qxXYGizMBtrP8axj5pZLGFKudl0mPHMajjNgvpAo1xkHjSM bLouRzEFZ8q4tSJMJcfxuPUhSDBCUSGZD8lvLkhh8Bqh1wCGgTduzq9QdS0hSJw5nIDt QQRgOU8QWRY6d4h8fgRAvuSlfyRqHZz17TANjCikapz7Yuj95Tdd6NFLOcd94Dw2UIcG 26baTenPcIcXXGx1HvP3Tu1aUT7ROAPgXw18A69KaAmHDMtmO1PXsoutCNNokQrdDepg PpYvMlvsoQEY5kQY/9zYtH1laP5TmnkuAk8AuZFdgW2Bfim5yOJbUFaOe3uZddx6Zql4 JDRQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1736927637; x=1737532437; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=F3fdHLVK61x8yyL/yphNE89C1K+GboFONSiIwYFJpPs=; b=cY/zN/LJlNIhrzH80SYPfVa2leitWs6T5BLmwTdBzvU4NY1U0FHGRJBSY7CssfJKSx NhUNMDXqtjnG3tYLKgYQL3Fdj7iuYR3FQCrkrbcna8GWAShJpyTf2LFMspAI6DEDbcZp M5lfRkUA33AJvzG7/lqzBqEBEZNCCtZrzV95gCM2rEbMqqNGQ5bRt3s/3oeYgLcAf7+R sfvo24lqMu2vXPtVD4dOBR0PVDC+oVq4Ap5pidcWQFdmPuiYXdbuIlpFLkUCHXTViVuN He5IBcbUbJ/sUr3NPWCppTSWPMOggsos+ViIGcTQABM0kIjR536n86GIxBEDmHVfwMIS 5XPg== X-Gm-Message-State: AOJu0YyYdCYaeV6akCLAn3akCIKtDgRpd29EQDZGdVVdRTMuIo/CuaWh rSY5CESoc5TBwukB4HLf7H4qkByZspSzAGL00NjNby09c0zxYzzWrtvqm3xJYtwOujYOXulKDRi T5e2jYwCZUjPrm5cUV2sgWdExHxvI8gWrH62DLZSLGxQb+SXkTzT5+6YLZMCd4RBH4fxC8rKZIW DILjc9+3l2WG5FsFMExJepx8gwhjJoAaa8b5iU0MRi8A== X-Gm-Gg: ASbGncv90sbDTyjUCBp+f0NZpwIC8tE4+2QPM7aS+SuzddKuYcWdC7KZQmhXPDkoC8q x96aBYnMkf21VZQuGXQgvcZsHGEjVfRlmMU4Omhxw+v55W0vQihiY9bTN+/koV4bwrJ8VCPmpFF pvauF5LSOXB5ahfzcZh0f8oMECOZwibwPYpNMhlZOuIoZ9iGXRUycTGlDpCUeTC5r8aFpBeRYsH wNSasJAujbSYAjbVNPcTEk3QP/Ey0sJYGg+krBDzIXqTZBNS3EI+Fknjn08bkVvyFvSPHGs0hUI gBs2PKUT X-Google-Smtp-Source: AGHT+IEmfzH842Fw1GdmwUEl7VeG/yL7+VLNDT4q15jnJ9oeMoshvXkAR0K92XkdscgDGGxhsssyig== X-Received: by 2002:a17:902:d2d2:b0:215:a3e4:d251 with SMTP id d9443c01a7336-21a83f36d6emr368079655ad.6.1736927636956; Tue, 14 Jan 2025 23:53:56 -0800 (PST) Received: from hsinchu02.internal.sifive.com ([210.176.154.34]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2f72c19a5d4sm839877a91.17.2025.01.14.23.53.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 14 Jan 2025 23:53:56 -0800 (PST) From: Monk Chiang To: gcc-patches@gcc.gnu.org, kito@gcc.gnu.org Cc: Monk Chiang , Greg McGary Subject: [PATCH v3 2/4] RISC-V: Add Zicfilp ISA extension. Date: Wed, 15 Jan 2025 15:53:45 +0800 Message-ID: <20250115075347.61344-2-monk.chiang@sifive.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250115075347.61344-1-monk.chiang@sifive.com> References: <20250115075347.61344-1-monk.chiang@sifive.com> MIME-Version: 1.0 X-Spam-Status: No, score=-12.6 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP, URIBL_BLACK autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces~patchwork=sourceware.org@gcc.gnu.org This patch only support landing pad value is 1. The next version will implement function signature based labeling scheme. RISC-V CFI SPEC: https://github.com/riscv/riscv-cfi gcc/ChangeLog: * gcc/common/config/riscv/riscv-common.cc: Add ZICFILP ISA string. * gcc/config.gcc: Add riscv-zicfilp.o * gcc/config/riscv/riscv-passes.def (INSERT_PASS_BEFORE): Insert landing pad instructions. * gcc/config/riscv/riscv-protos.h (make_pass_insert_landing_pad): Declare. * gcc/config/riscv/riscv-zicfilp.cc: New file. * gcc/config/riscv/riscv.cc (riscv_trampoline_init): Add landing pad instructions. (riscv_legitimize_call_address): Likewise. (riscv_output_mi_thunk): Likewise. * gcc/config/riscv/riscv.h: Update. * gcc/config/riscv/riscv.md: Add landing pad patterns. * gcc/config/riscv/riscv.opt (TARGET_ZICFILP): Define. * gcc/config/riscv/t-riscv: Add build rule for riscv-zicfilp.o gcc/testsuite/ChangeLog: * gcc/testsuite/gcc.target/riscv/interrupt-no-lpad.c: New test. * gcc/testsuite/gcc.target/riscv/zicfilp-call.c: New test. Co-Developed-by: Greg McGary --- gcc/common/config/riscv/riscv-common.cc | 3 + gcc/config.gcc | 2 +- gcc/config/riscv/riscv-passes.def | 1 + gcc/config/riscv/riscv-protos.h | 1 + gcc/config/riscv/riscv-zicfilp.cc | 169 ++++++++++++++++++ gcc/config/riscv/riscv.cc | 145 ++++++++++++--- gcc/config/riscv/riscv.h | 13 +- gcc/config/riscv/riscv.md | 73 +++++++- gcc/config/riscv/riscv.opt | 2 + gcc/config/riscv/t-riscv | 9 + .../gcc.target/riscv/interrupt-no-lpad.c | 7 + gcc/testsuite/gcc.target/riscv/zicfilp-call.c | 14 ++ 12 files changed, 402 insertions(+), 37 deletions(-) create mode 100644 gcc/config/riscv/riscv-zicfilp.cc create mode 100644 gcc/testsuite/gcc.target/riscv/interrupt-no-lpad.c create mode 100644 gcc/testsuite/gcc.target/riscv/zicfilp-call.c diff --git a/gcc/common/config/riscv/riscv-common.cc b/gcc/common/config/riscv/riscv-common.cc index 8e8b6107a6d..5038f0eb959 100644 --- a/gcc/common/config/riscv/riscv-common.cc +++ b/gcc/common/config/riscv/riscv-common.cc @@ -113,6 +113,7 @@ static const riscv_implied_info_t riscv_implied_info[] = {"zicfiss", "zicsr"}, {"zicfiss", "zimop"}, + {"zicfilp", "zicsr"}, {"zk", "zkn"}, {"zk", "zkr"}, @@ -329,6 +330,7 @@ static const struct riscv_ext_version riscv_ext_version_table[] = {"ziccrse", ISA_SPEC_CLASS_NONE, 1, 0}, {"zicfiss", ISA_SPEC_CLASS_NONE, 1, 0}, + {"zicfilp", ISA_SPEC_CLASS_NONE, 1, 0}, {"zimop", ISA_SPEC_CLASS_NONE, 1, 0}, {"zcmop", ISA_SPEC_CLASS_NONE, 1, 0}, @@ -1653,6 +1655,7 @@ static const riscv_ext_flag_table_t riscv_ext_flag_table[] = RISCV_EXT_FLAG_ENTRY ("zic64b", x_riscv_zicmo_subext, MASK_ZIC64B), RISCV_EXT_FLAG_ENTRY ("zicfiss", x_riscv_zi_subext, MASK_ZICFISS), + RISCV_EXT_FLAG_ENTRY ("zicfilp", x_riscv_zi_subext, MASK_ZICFILP), RISCV_EXT_FLAG_ENTRY ("zimop", x_riscv_mop_subext, MASK_ZIMOP), RISCV_EXT_FLAG_ENTRY ("zcmop", x_riscv_mop_subext, MASK_ZCMOP), diff --git a/gcc/config.gcc b/gcc/config.gcc index 55e37146ee0..87fed823118 100644 --- a/gcc/config.gcc +++ b/gcc/config.gcc @@ -553,7 +553,7 @@ riscv*) extra_objs="riscv-builtins.o riscv-c.o riscv-sr.o riscv-shorten-memrefs.o riscv-selftests.o riscv-string.o" extra_objs="${extra_objs} riscv-v.o riscv-vsetvl.o riscv-vector-costs.o riscv-avlprop.o" extra_objs="${extra_objs} riscv-vector-builtins.o riscv-vector-builtins-shapes.o riscv-vector-builtins-bases.o sifive-vector-builtins-bases.o" - extra_objs="${extra_objs} thead.o riscv-target-attr.o" + extra_objs="${extra_objs} thead.o riscv-target-attr.o riscv-zicfilp.o" d_target_objs="riscv-d.o" extra_headers="riscv_vector.h riscv_crypto.h riscv_bitmanip.h riscv_th_vector.h riscv_cmo.h" target_gtfiles="$target_gtfiles \$(srcdir)/config/riscv/riscv-vector-builtins.cc" diff --git a/gcc/config/riscv/riscv-passes.def b/gcc/config/riscv/riscv-passes.def index cbea23c8b44..7e6a2a0e53d 100644 --- a/gcc/config/riscv/riscv-passes.def +++ b/gcc/config/riscv/riscv-passes.def @@ -20,3 +20,4 @@ INSERT_PASS_AFTER (pass_rtl_store_motion, 1, pass_shorten_memrefs); INSERT_PASS_AFTER (pass_split_all_insns, 1, pass_avlprop); INSERT_PASS_BEFORE (pass_fast_rtl_dce, 1, pass_vsetvl); +INSERT_PASS_BEFORE (pass_shorten_branches, 1, pass_insert_landing_pad); diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h index dd3b36d47a6..6362380ec6c 100644 --- a/gcc/config/riscv/riscv-protos.h +++ b/gcc/config/riscv/riscv-protos.h @@ -200,6 +200,7 @@ extern bool riscv_hard_regno_rename_ok (unsigned, unsigned); rtl_opt_pass * make_pass_shorten_memrefs (gcc::context *ctxt); rtl_opt_pass * make_pass_avlprop (gcc::context *ctxt); rtl_opt_pass * make_pass_vsetvl (gcc::context *ctxt); +rtl_opt_pass * make_pass_insert_landing_pad (gcc::context *ctxt); /* Routines implemented in riscv-string.c. */ extern bool riscv_expand_block_compare (rtx, rtx, rtx, rtx); diff --git a/gcc/config/riscv/riscv-zicfilp.cc b/gcc/config/riscv/riscv-zicfilp.cc new file mode 100644 index 00000000000..b30869ae297 --- /dev/null +++ b/gcc/config/riscv/riscv-zicfilp.cc @@ -0,0 +1,169 @@ +/* Branch Target Identification for RISCV architecture. + Copyright (C) 2019-2024 Free Software Foundation, Inc. + Contributed by Arm Ltd. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + GCC is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING3. If not see + . */ + +#define IN_TARGET_CODE 1 + +#include "config.h" +#define INCLUDE_STRING +#include "system.h" +#include "coretypes.h" +#include "backend.h" +#include "target.h" +#include "rtl.h" +#include "tree.h" +#include "memmodel.h" +#include "gimple.h" +#include "tm_p.h" +#include "stringpool.h" +#include "attribs.h" +#include "expr.h" +#include "emit-rtl.h" +#include "gimplify.h" +#include "gimple-iterator.h" +#include "dumpfile.h" +#include "rtl-iter.h" +#include "cfgrtl.h" +#include "tree-pass.h" +#include "cgraph.h" +#include "output.h" + +/* This pass implements forward-CFI landing pad checks for RISCV. This is + a security feature similar to BTI (branch target identification) in + AArch64 and IBT (indirect branch tracking)in X86. A LPAD (landing-pad + check) instruction is used to guard against the execution of + instructions which are not the intended target of an indirect branch. + + When forward-CFI is disabled or unimplemented in the CPU, the + landing-pad check label instructions behave as NOP. When implemented in + the CPU, and enabled, the destination of an indirect branch must be + LPAD insn. Otherwise, the CPU reaises an exception. + + In order to enable this mechanism, this pass iterates through the + control flow of the code and adds appropriate LPAD instructions at the + beginning of any function that can be called indirectly, and for targets + of indirect jumps, i.e., jump table targets, non-local goto targets, and + labels that might be referenced by variables, constant pools, etc + (NOTE_INSN_DELETED_LABEL). */ + +namespace { + +const pass_data pass_data_insert_landing_pad = +{ + RTL_PASS, /* type. */ + "zisslpcfi", /* name. */ + OPTGROUP_NONE, /* optinfo_flags. */ + TV_MACH_DEP, /* tv_id. */ + 0, /* properties_required. */ + 0, /* properties_provided. */ + 0, /* properties_destroyed. */ + 0, /* todo_flags_start. */ + 0, /* todo_flags_finish. */ +}; + +static bool +is_interrupt_handler_p (tree type) +{ + return lookup_attribute ("interrupt", TYPE_ATTRIBUTES (type)) != NULL; +} + +/* Insert landing-pad check instructions. This is a late RTL pass that runs + before branch shortening. */ +static unsigned int +rest_of_insert_landing_pad (void) +{ + timevar_push (TV_MACH_DEP); + + struct cgraph_node *c_node; + rtx lpad_insn; + rtx_insn *insn; + basic_block bb; + + bb = 0; + FOR_EACH_BB_FN (bb, cfun) + { + for (insn = BB_HEAD (bb); insn != NEXT_INSN (BB_END (bb)); + insn = NEXT_INSN (insn)) + { + /* If a label is marked to be preserved or can be a non-local goto + target, it must be protected with a lpad instruction. */ + if (LABEL_P (insn) + && (LABEL_PRESERVE_P (insn) + || bb->flags & BB_NON_LOCAL_GOTO_TARGET)) + { + emit_insn_before (gen_lpad_align (), insn); + emit_insn_after (gen_lpad (const0_rtx), insn); + continue; + } + + if (INSN_P (insn) && INSN_CODE (insn) == CODE_FOR_gpr_save) + { + emit_move_insn (RISCV_CALL_ADDRESS_LPAD (Pmode), const0_rtx); + emit_insn_before (gen_lpad_align (), insn); + emit_insn_after (gen_lpad (const0_rtx), insn); + continue; + } + + if (INSN_P (insn) && INSN_CODE (insn) == CODE_FOR_gpr_restore) + emit_move_insn (RISCV_CALL_ADDRESS_LPAD (Pmode), const0_rtx); + + } + } + + c_node = cgraph_node::get (cfun->decl); + if (!c_node->only_called_directly_p () + && !is_interrupt_handler_p (TREE_TYPE (cfun->decl))) + { + bb = ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb; + insn = BB_HEAD (bb); + lpad_insn = gen_lpad (const0_rtx); + emit_insn_before (lpad_insn, insn); + } + + timevar_pop (TV_MACH_DEP); + return 0; +} + +class pass_insert_landing_pad : public rtl_opt_pass +{ +public: + pass_insert_landing_pad (gcc::context *ctxt) + : rtl_opt_pass (pass_data_insert_landing_pad, ctxt) + {} + + /* opt_pass methods: */ + virtual bool gate (function *) + { + return TARGET_ZICFILP; + } + + virtual unsigned int execute (function *) + { + return rest_of_insert_landing_pad (); + } + +}; // class pass_insert_landing_pad + +} // anon namespace + +rtl_opt_pass * +make_pass_insert_landing_pad (gcc::context *ctxt) +{ + return new pass_insert_landing_pad (ctxt); +} diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index cd37b492183..4afb0b95839 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -6681,8 +6681,20 @@ riscv_legitimize_call_address (rtx addr) { rtx reg = RISCV_CALL_ADDRESS_TEMP (Pmode); riscv_emit_move (reg, addr); + + if (TARGET_ZICFILP) + { + rtx sw_guarded = RISCV_CALL_ADDRESS_LPAD (Pmode); + emit_insn (gen_set_guarded (Pmode, reg)); + return sw_guarded; + } + return reg; } + + if (TARGET_ZICFILP && REG_P (addr)) + emit_insn (gen_set_lpl (Pmode, const0_rtx)); + return addr; } @@ -10342,6 +10354,9 @@ 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) + emit_insn(gen_lpad (const0_rtx)); + /* Determine if we can use a sibcall to call FUNCTION directly. */ fnaddr = gen_rtx_MEM (FUNCTION_MODE, XEXP (DECL_RTL (function), 0)); @@ -10853,12 +10868,17 @@ riscv_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value) { rtx addr, end_addr, mem; uint32_t trampoline[4]; + uint32_t trampoline_cfi[6]; unsigned int i; HOST_WIDE_INT static_chain_offset, target_function_offset; + HOST_WIDE_INT lp_value = 0; /* Work out the offsets of the pointers from the start of the trampoline code. */ - gcc_assert (ARRAY_SIZE (trampoline) * 4 == TRAMPOLINE_CODE_SIZE); + if (!TARGET_ZICFILP) + gcc_assert (ARRAY_SIZE (trampoline) * 4 == TRAMPOLINE_CODE_SIZE); + else + gcc_assert (ARRAY_SIZE (trampoline_cfi) * 4 == TRAMPOLINE_CODE_SIZE); /* Get pointers to the beginning and end of the code block. */ addr = force_reg (Pmode, XEXP (m_tramp, 0)); @@ -10880,6 +10900,17 @@ riscv_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value) unsigned HOST_WIDE_INT lo_chain_code, lo_func_code; rtx uimm_mask = force_reg (SImode, gen_int_mode (-IMM_REACH, SImode)); + unsigned insn_count = 0; + + /* Insert lpad, if zicfilp is enabled. */ + if (TARGET_ZICFILP) + { + unsigned HOST_WIDE_INT lpad_code; + lpad_code = OPCODE_AUIPC | (0 << SHIFT_RD) | (lp_value << IMM_BITS); + mem = adjust_address (m_tramp, SImode, 0); + riscv_emit_move (mem, gen_int_mode (lpad_code, SImode)); + insn_count++; + } /* 0xfff. */ rtx imm12_mask = gen_reg_rtx (SImode); @@ -10893,11 +10924,14 @@ riscv_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value) hi_chain = riscv_force_binary (SImode, AND, hi_chain, uimm_mask); lui_hi_chain_code = OPCODE_LUI | (STATIC_CHAIN_REGNUM << SHIFT_RD); + rtx lui_hi_chain_value = force_reg (SImode, gen_int_mode (lui_hi_chain_code, + SImode)); rtx lui_hi_chain = riscv_force_binary (SImode, IOR, hi_chain, - gen_int_mode (lui_hi_chain_code, SImode)); - - mem = adjust_address (m_tramp, SImode, 0); + lui_hi_chain_value); + mem = adjust_address (m_tramp, SImode, + insn_count * GET_MODE_SIZE (SImode)); riscv_emit_move (mem, riscv_swap_instruction (lui_hi_chain)); + insn_count++; /* Gen lui t0, hi(func). */ rtx hi_func = riscv_force_binary (SImode, PLUS, target_function, @@ -10908,8 +10942,10 @@ riscv_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value) rtx lui_hi_func = riscv_force_binary (SImode, IOR, hi_func, gen_int_mode (lui_hi_func_code, SImode)); - mem = adjust_address (m_tramp, SImode, 1 * GET_MODE_SIZE (SImode)); + mem = adjust_address (m_tramp, SImode, + insn_count * GET_MODE_SIZE (SImode)); riscv_emit_move (mem, riscv_swap_instruction (lui_hi_func)); + insn_count++; /* Gen addi t2, t2, lo(chain). */ rtx lo_chain = riscv_force_binary (SImode, AND, chain_value, @@ -10923,8 +10959,23 @@ riscv_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value) rtx addi_lo_chain = riscv_force_binary (SImode, IOR, lo_chain, force_reg (SImode, GEN_INT (lo_chain_code))); - mem = adjust_address (m_tramp, SImode, 2 * GET_MODE_SIZE (SImode)); + mem = adjust_address (m_tramp, SImode, + insn_count * GET_MODE_SIZE (SImode)); riscv_emit_move (mem, riscv_swap_instruction (addi_lo_chain)); + insn_count++; + + /* For zicfilp only, insert lui t2, 1, because use jr t0. */ + if (TARGET_ZICFILP) + { + unsigned HOST_WIDE_INT set_lpl_code; + set_lpl_code = OPCODE_LUI + | (RISCV_CALL_ADDRESS_LPAD_REGNUM << SHIFT_RD) + | (lp_value << IMM_BITS); + mem = adjust_address (m_tramp, SImode, + insn_count * GET_MODE_SIZE (SImode)); + riscv_emit_move (mem, gen_int_mode (set_lpl_code, SImode)); + insn_count++; + } /* Gen jr t0, lo(func). */ rtx lo_func = riscv_force_binary (SImode, AND, target_function, @@ -10936,7 +10987,7 @@ riscv_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value) rtx jr_lo_func = riscv_force_binary (SImode, IOR, lo_func, force_reg (SImode, GEN_INT (lo_func_code))); - mem = adjust_address (m_tramp, SImode, 3 * GET_MODE_SIZE (SImode)); + mem = adjust_address (m_tramp, SImode, insn_count * GET_MODE_SIZE (SImode)); riscv_emit_move (mem, riscv_swap_instruction (jr_lo_func)); } else @@ -10944,29 +10995,65 @@ 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); - /* auipc t2, 0 - l[wd] t0, target_function_offset(t2) - l[wd] t2, static_chain_offset(t2) - jr t0 - */ - trampoline[0] = OPCODE_AUIPC | (STATIC_CHAIN_REGNUM << SHIFT_RD); - trampoline[1] = (Pmode == DImode ? OPCODE_LD : OPCODE_LW) - | (RISCV_PROLOGUE_TEMP_REGNUM << SHIFT_RD) - | (STATIC_CHAIN_REGNUM << SHIFT_RS1) - | (target_function_offset << SHIFT_IMM); - trampoline[2] = (Pmode == DImode ? OPCODE_LD : OPCODE_LW) - | (STATIC_CHAIN_REGNUM << SHIFT_RD) - | (STATIC_CHAIN_REGNUM << SHIFT_RS1) - | (static_chain_offset << SHIFT_IMM); - trampoline[3] = OPCODE_JALR | (RISCV_PROLOGUE_TEMP_REGNUM << SHIFT_RS1); - - /* Copy the trampoline code. */ - for (i = 0; i < ARRAY_SIZE (trampoline); i++) + if (!TARGET_ZICFILP) { - if (BYTES_BIG_ENDIAN) - trampoline[i] = __builtin_bswap32(trampoline[i]); - mem = adjust_address (m_tramp, SImode, i * GET_MODE_SIZE (SImode)); - riscv_emit_move (mem, gen_int_mode (trampoline[i], SImode)); + /* auipc t2, 0 + l[wd] t0, (target_function_offset)(t2) + l[wd] t2, (static_chain_offset)(t2) + jr t0 + */ + trampoline[0] = OPCODE_AUIPC | (STATIC_CHAIN_REGNUM << SHIFT_RD); + trampoline[1] = (Pmode == DImode ? OPCODE_LD : OPCODE_LW) + | (RISCV_PROLOGUE_TEMP_REGNUM << SHIFT_RD) + | (STATIC_CHAIN_REGNUM << SHIFT_RS1) + | (target_function_offset << SHIFT_IMM); + trampoline[2] = (Pmode == DImode ? OPCODE_LD : OPCODE_LW) + | (STATIC_CHAIN_REGNUM << SHIFT_RD) + | (STATIC_CHAIN_REGNUM << SHIFT_RS1) + | (static_chain_offset << SHIFT_IMM); + trampoline[3] = OPCODE_JALR | (RISCV_PROLOGUE_TEMP_REGNUM << SHIFT_RS1); + + /* Copy the trampoline code. */ + for (i = 0; i < ARRAY_SIZE (trampoline); i++) + { + if (BYTES_BIG_ENDIAN) + trampoline[i] = __builtin_bswap32 (trampoline[i]); + mem = adjust_address (m_tramp, SImode, i * GET_MODE_SIZE (SImode)); + riscv_emit_move (mem, gen_int_mode (trampoline[i], SImode)); + } + } + else + { + /* lpad 1 + auipc t3, 0 + l[wd] t0, (target_function_offset - 4)(t3) + l[wd] t3, (static_chain_offset - 4)(t3) + lui t2, 1 + jr t0 + */ + trampoline_cfi[0] = OPCODE_AUIPC | (0 << SHIFT_RD) | (lp_value << IMM_BITS); + trampoline_cfi[1] = OPCODE_AUIPC | (STATIC_CHAIN_REGNUM << SHIFT_RD); + trampoline_cfi[2] = (Pmode == DImode ? OPCODE_LD : OPCODE_LW) + | (RISCV_PROLOGUE_TEMP_REGNUM << SHIFT_RD) + | (STATIC_CHAIN_REGNUM << SHIFT_RS1) + | ((target_function_offset - 4) << SHIFT_IMM); + trampoline_cfi[3] = (Pmode == DImode ? OPCODE_LD : OPCODE_LW) + | (STATIC_CHAIN_REGNUM << SHIFT_RD) + | (STATIC_CHAIN_REGNUM << SHIFT_RS1) + | ((static_chain_offset - 4) << SHIFT_IMM); + trampoline_cfi[4] = OPCODE_LUI + | (RISCV_CALL_ADDRESS_LPAD_REGNUM << SHIFT_RD) + | (lp_value << IMM_BITS); + trampoline_cfi[5] = OPCODE_JALR | (RISCV_PROLOGUE_TEMP_REGNUM << SHIFT_RS1); + + /* Copy the trampoline code. */ + for (i = 0; i < ARRAY_SIZE (trampoline_cfi); i++) + { + if (BYTES_BIG_ENDIAN) + trampoline_cfi[i] = __builtin_bswap32 (trampoline_cfi[i]); + mem = adjust_address (m_tramp, SImode, i * GET_MODE_SIZE (SImode)); + riscv_emit_move (mem, gen_int_mode (trampoline_cfi[i], SImode)); + } } /* Set up the static chain pointer field. */ diff --git a/gcc/config/riscv/riscv.h b/gcc/config/riscv/riscv.h index 93e88fe885d..073b9e4f2bd 100644 --- a/gcc/config/riscv/riscv.h +++ b/gcc/config/riscv/riscv.h @@ -190,7 +190,8 @@ ASM_MISA_SPEC #define PARM_BOUNDARY BITS_PER_WORD /* Allocation boundary (in *bits*) for the code of a function. */ -#define FUNCTION_BOUNDARY ((TARGET_RVC || TARGET_ZCA) ? 16 : 32) +#define FUNCTION_BOUNDARY \ + (((TARGET_RVC || TARGET_ZCA) && !TARGET_ZICFILP) ? 16 : 32) /* The smallest supported stack boundary the calling convention supports. */ #define STACK_BOUNDARY \ @@ -413,7 +414,8 @@ ASM_MISA_SPEC #define RISCV_DWARF_VLENB (4096 + 0xc22) /* Register in which static-chain is passed to a function. */ -#define STATIC_CHAIN_REGNUM (GP_TEMP_FIRST + 2) +#define STATIC_CHAIN_REGNUM \ + ((TARGET_ZICFILP) ? (GP_TEMP_FIRST + 23) : (GP_TEMP_FIRST + 2)) /* Registers used as temporaries in prologue/epilogue code. @@ -436,6 +438,10 @@ ASM_MISA_SPEC #define RISCV_CALL_ADDRESS_TEMP(MODE) \ gen_rtx_REG (MODE, RISCV_CALL_ADDRESS_TEMP_REGNUM) +#define RISCV_CALL_ADDRESS_LPAD_REGNUM (GP_TEMP_FIRST + 2) +#define RISCV_CALL_ADDRESS_LPAD(MODE) \ + gen_rtx_REG (MODE, RISCV_CALL_ADDRESS_LPAD_REGNUM) + #define RETURN_ADDR_MASK (1 << RETURN_ADDR_REGNUM) #define S0_MASK (1 << S0_REGNUM) #define S1_MASK (1 << S1_REGNUM) @@ -821,7 +827,8 @@ extern enum riscv_cc get_riscv_cc (const rtx use); /* Trampolines are a block of code followed by two pointers. */ -#define TRAMPOLINE_CODE_SIZE 16 +#define TRAMPOLINE_CODE_SIZE ((TARGET_ZICFILP) ? 24 : 16) + #define TRAMPOLINE_SIZE \ ((Pmode == SImode) \ ? TRAMPOLINE_CODE_SIZE \ diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md index 21094395184..5b4c81bb9e0 100644 --- a/gcc/config/riscv/riscv.md +++ b/gcc/config/riscv/riscv.md @@ -105,6 +105,12 @@ UNSPECV_SSPOPCHK UNSPECV_SSRDP UNSPECV_SSP + + ;; ZICFILP + UNSPECV_LPAD + UNSPECV_SETLPL + UNSPECV_LPAD_ALIGN + UNSPECV_SET_GUARDED ]) (define_c_enum "unspecv" [ @@ -155,6 +161,7 @@ (TP_REGNUM 4) (T0_REGNUM 5) (T1_REGNUM 6) + (T2_REGNUM 7) (S0_REGNUM 8) (S1_REGNUM 9) (A0_REGNUM 10) @@ -3709,11 +3716,18 @@ [(set (pc) (match_operand 0 "register_operand"))] "" { + if (TARGET_ZICFILP) + emit_insn (gen_set_lpl (Pmode, const0_rtx)); + operands[0] = force_reg (Pmode, operands[0]); + if (TARGET_ZICFILP) + emit_use (gen_rtx_REG (Pmode, T2_REGNUM)); + if (Pmode == SImode) emit_jump_insn (gen_indirect_jumpsi (operands[0])); else emit_jump_insn (gen_indirect_jumpdi (operands[0])); + DONE; }) @@ -3734,21 +3748,42 @@ gen_rtx_LABEL_REF (Pmode, operands[1]), NULL_RTX, 0, OPTAB_DIRECT); - if (CASE_VECTOR_PC_RELATIVE && Pmode == DImode) - emit_jump_insn (gen_tablejumpdi (operands[0], operands[1])); + if (TARGET_ZICFILP) + { + rtx t2 = RISCV_CALL_ADDRESS_LPAD (GET_MODE (operands[0])); + emit_move_insn (t2, operands[0]); + + if (CASE_VECTOR_PC_RELATIVE && Pmode == DImode) + emit_jump_insn (gen_tablejump_cfidi (operands[1])); + else + emit_jump_insn (gen_tablejump_cfisi (operands[1])); + } else - emit_jump_insn (gen_tablejumpsi (operands[0], operands[1])); + { + if (CASE_VECTOR_PC_RELATIVE && Pmode == DImode) + emit_jump_insn (gen_tablejumpdi (operands[0], operands[1])); + else + emit_jump_insn (gen_tablejumpsi (operands[0], operands[1])); + } DONE; }) (define_insn "tablejump" [(set (pc) (match_operand:GPR 0 "register_operand" "l")) (use (label_ref (match_operand 1 "" "")))] - "" + "!TARGET_ZICFILP" "jr\t%0" [(set_attr "type" "jalr") (set_attr "mode" "none")]) +(define_insn "tablejump_cfi" + [(set (pc) (reg:GPR T2_REGNUM)) + (use (label_ref (match_operand 0 "")))] + "TARGET_ZICFILP" + "jr\tt2" + [(set_attr "type" "jalr") + (set_attr "mode" "none")]) + ;; ;; .................... ;; @@ -4718,6 +4753,36 @@ [(set_attr "type" "arith") (set_attr "mode" "")]) +;; Lading pad. + +(define_insn "lpad" + [(unspec_volatile [(match_operand 0 "immediate_operand" "i")] UNSPECV_LPAD)] + "TARGET_ZICFILP" + "lpad\t%0" + [(set_attr "type" "auipc")]) + +(define_insn "@set_lpl" + [(set (reg:GPR T2_REGNUM) + (unspec_volatile [(match_operand:GPR 0 "immediate_operand" "i")] UNSPECV_SETLPL))] + "TARGET_ZICFILP" + "lui\tt2,%0" + [(set_attr "type" "const") + (set_attr "mode" "")]) + +(define_insn "lpad_align" + [(unspec_volatile [(const_int 0)] UNSPECV_LPAD_ALIGN)] + "TARGET_ZICFILP" + ".align 2" + [(set_attr "type" "nop")]) + +(define_insn "@set_guarded" + [(set (reg:GPR T2_REGNUM) + (unspec_volatile [(match_operand:GPR 0 "register_operand" "r")] UNSPECV_SET_GUARDED))] + "TARGET_ZICFILP" + "mv\tt2,%0" + [(set_attr "type" "move") + (set_attr "mode" "")]) + (include "bitmanip.md") (include "crypto.md") (include "sync.md") diff --git a/gcc/config/riscv/riscv.opt b/gcc/config/riscv/riscv.opt index 4a43bfd7bc6..f51f8fd1cdf 100644 --- a/gcc/config/riscv/riscv.opt +++ b/gcc/config/riscv/riscv.opt @@ -255,6 +255,8 @@ Mask(ZICCRSE) Var(riscv_zi_subext) Mask(ZICFISS) Var(riscv_zi_subext) +Mask(ZICFILP) Var(riscv_zi_subext) + TargetVariable int riscv_za_subext diff --git a/gcc/config/riscv/t-riscv b/gcc/config/riscv/t-riscv index bc67d8719fa..6493087fe51 100644 --- a/gcc/config/riscv/t-riscv +++ b/gcc/config/riscv/t-riscv @@ -145,6 +145,15 @@ thead.o: $(srcdir)/config/riscv/thead.cc \ $(COMPILE) $< $(POSTCOMPILE) +riscv-zicfilp.o: $(srcdir)/config/riscv/riscv-zicfilp.cc \ + $(CONFIG_H) $(SYSTEM_H) $(TM_H) $(REGS_H) insn-config.h $(RTL_BASE_H) \ + dominance.h cfg.h cfganal.h $(BASIC_BLOCK_H) $(INSN_ATTR_H) $(RECOG_H) \ + output.h hash-map.h $(DF_H) $(OBSTACK_H) $(TARGET_H) $(RTL_H) \ + $(CONTEXT_H) $(TREE_PASS_H) regrename.h \ + $(srcdir)/config/riscv/riscv-protos.h + $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \ + $(srcdir)/config/riscv/riscv-zicfilp.cc + PASSES_EXTRA += $(srcdir)/config/riscv/riscv-passes.def $(common_out_file): $(srcdir)/config/riscv/riscv-cores.def \ diff --git a/gcc/testsuite/gcc.target/riscv/interrupt-no-lpad.c b/gcc/testsuite/gcc.target/riscv/interrupt-no-lpad.c new file mode 100644 index 00000000000..ff512b98c61 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/interrupt-no-lpad.c @@ -0,0 +1,7 @@ +/* { dg-do compile { target { riscv64*-*-* } } } */ +/* { dg-options "-march=rv64gc_zicfilp -mabi=lp64d" } */ +void __attribute__ ((interrupt)) +foo (void) +{ +} +/* { dg-final { scan-assembler-not "lpad\t" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/zicfilp-call.c b/gcc/testsuite/gcc.target/riscv/zicfilp-call.c new file mode 100644 index 00000000000..75c8b32faa3 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/zicfilp-call.c @@ -0,0 +1,14 @@ +/* { dg-do compile { target { riscv64*-*-* } } } */ +/* { dg-options "-O2 -fPIE -march=rv64gc_zicfilp -mabi=lp64d" } */ +/* { dg-skip-if "" { *-*-* } { "-O0" } } */ + +extern void _dl_find_object_init (void); + +void +_dl_non_dynamic_init (void) +{ + extern __typeof__ (_dl_find_object_init) _dl_find_object_init __attribute__ ((weak)); + (_dl_find_object_init != ((void *) 0) ? _dl_find_object_init () : (void)0); +} + +/* { dg-final { scan-assembler-times "mv\tt2" 1 } } */ From patchwork Wed Jan 15 07:53:46 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Monk Chiang X-Patchwork-Id: 104807 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 4692D385482F for ; Wed, 15 Jan 2025 07:56:31 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 4692D385482F Authentication-Results: sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=sifive.com header.i=@sifive.com header.a=rsa-sha256 header.s=google header.b=kXoiX/BZ X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-pl1-x62c.google.com (mail-pl1-x62c.google.com [IPv6:2607:f8b0:4864:20::62c]) by sourceware.org (Postfix) with ESMTPS id 4B2A13854828 for ; Wed, 15 Jan 2025 07:54:01 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 4B2A13854828 Authentication-Results: sourceware.org; dmarc=pass (p=reject dis=none) header.from=sifive.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=sifive.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 4B2A13854828 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::62c ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1736927641; cv=none; b=xRRM/OzfwGq3JjlIGjHofL94SHQGlCfzc0N5dd8pknXr3aGfeMGO6v7o8Yg3cxPXHY44DsEOXH3a1TWAlLbniC69Es1vCMC6QkMNkb+RNw40KdKEyn6IEzveZh0qy6mjtko6u0pcIeX3MAjtdMmF6OZJjbEr9NF9SVueAaKDiBo= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1736927641; c=relaxed/simple; bh=q5kMaWPCJ93wxujTRNBIXdFMLWCjAeeeUN6X1QqiOhE=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=L5cR/x6fWQkF+jLwx625746u1urDRJFt5YkguBIT9pDasQqW1/YFPaY1UBrKFMXe8/+1UXxDluy4IV0Rco2kChiFKGWOVFl1UzpjN/UddrblNUXy/LSkYn+PHiDnyvMqmqaIgl/T3bYPE0itEZhl6io3519u717cuXG8+FGCfVY= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 4B2A13854828 Received: by mail-pl1-x62c.google.com with SMTP id d9443c01a7336-218c8aca5f1so138734055ad.0 for ; Tue, 14 Jan 2025 23:54:01 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sifive.com; s=google; t=1736927640; x=1737532440; darn=gcc.gnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=PVjHN2NjUkb48UEl1B2aX2T7J2mUrg2C1ujBONEl9JM=; b=kXoiX/BZ4QKD2lQBbkXC6cwg9Em34Kk6rL76Uh9o20gecu2gF0RD+njtVQQfRlo1Sm bbhd0cYDQth+cS9eNhIe1lIFMXWt6UgbPdQaUVOzXio7O2bjlAyJjfnVdxE62OlDHhBh JJSaq1vCPwq8QfFBqDaaYpIlbCPeK1JbPc2FCWz8N8HEpFrDD8eioiwqCcTAdGvV5gUu rXxVmP+gilehySQvmnyHlBRUQ0KBgNl1sZUxqPV8xN7uGIUyd3LL7Ny/gga//08qb6pK WN+rg/DdkK4WzDDPZLG6b83LkgrZox/qALgRxnSKsIUVdRUPENqXj+8RbmQSbR5f7mmX v0JA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1736927640; x=1737532440; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=PVjHN2NjUkb48UEl1B2aX2T7J2mUrg2C1ujBONEl9JM=; b=i2VZgM/YaP/DsyEYCw7MjI6aGFnsQmw6ixcV2h19SguqpRP1lk6+63XRN8f6OOBDsz SJtmTxursBl0HnYPSC08hsovlxtBpOqMOqFGqKJaThYmGl82CKxjwn4ZyJ4j4p3pDIrM AeCgoZf8M7BiWktg4m+4B0pwYGmx/ljRefPbQ22urKE5lH1YtB3e8GDapoSQjsdikAWv 1jlm4fqv8RgcdVswa9+FvRd0Ak1LrCviNvzmUpgciJvrKc2SNKS3pXk+kTRS+Ak1gPSW cm2Q1KPpuEKtl8tZsn6yol8VO07ETnkJD4HwFN0z4HgIX7aMdIEQLl/8hKoaFCutT5ie v0KQ== X-Gm-Message-State: AOJu0YwxHa8i8UWqyuH1gFjQCKs8dO8R0DmnIgtnQ3zrBnsgOY2igscc DTn4QKyPbMczarN5tnv9GMIenzAQddD3C3byliuSbIEKKq1kt/jXBSulotCWhMjj9qOef+Vj3RS MT/LPgnOg5KmdcmZg0Kj8Jh49jZky6Qo7QpAtv4lC8cGXx7tTTVr3v4YbfmpB/kH5/D5RK1AQZX qNHMPuF8PGlA4ztD0vglkTGQVrvpZrbAjJuNQ+sO3uHw== X-Gm-Gg: ASbGnct/cv5moqE/NB4LxFtwaS4snWVygD25F7XdKdYcqaPTZT9Lu9kWcQN/yntkuhx RSHikY7yPD5tFLhgQvBVr0NXc17K97DyPu1x6rru12kxbgeRMUx9QS6q809FzWgEZhXq5sNVaM3 Brf8og/BydRypzfbQrIJpaV4AB0LsGB042Ax/5t/N2TGMqCq0+hyMrBwqgv5CyLzKQN2E3YkLWR WAktL55dL6+zkpODF5le/x8tU6n9N9CQpsKeuATRD95aF5dgNLQWkr4h8/yp6oj0y2Ulh0uWYYb 3rmqh3Of X-Google-Smtp-Source: AGHT+IHEqCB7pZKxMkfXqrf9A4JSE8H3v6ecC8ELZqNZMeey5kpxEqu/Cv0HXslkeDiUkq4JfM9gFQ== X-Received: by 2002:a17:902:cec3:b0:215:b45a:6a5e with SMTP id d9443c01a7336-21a83f57228mr363460475ad.18.1736927639966; Tue, 14 Jan 2025 23:53:59 -0800 (PST) Received: from hsinchu02.internal.sifive.com ([210.176.154.34]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2f72c19a5d4sm839877a91.17.2025.01.14.23.53.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 14 Jan 2025 23:53:59 -0800 (PST) From: Monk Chiang To: gcc-patches@gcc.gnu.org, kito@gcc.gnu.org Cc: Monk Chiang Subject: [PATCH v3 3/4] RISC-V: Add .note.gnu.property for ZICFILP and ZICFISS ISA extension Date: Wed, 15 Jan 2025 15:53:46 +0800 Message-ID: <20250115075347.61344-3-monk.chiang@sifive.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250115075347.61344-1-monk.chiang@sifive.com> References: <20250115075347.61344-1-monk.chiang@sifive.com> MIME-Version: 1.0 X-Spam-Status: No, score=-12.6 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP, URIBL_BLACK autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces~patchwork=sourceware.org@gcc.gnu.org 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. --- gcc/config/riscv/linux.h | 2 + gcc/config/riscv/riscv.cc | 50 ++++++++++++++++++++++ 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 +++ 6 files changed, 129 insertions(+), 1 deletion(-) diff --git a/gcc/config/riscv/linux.h b/gcc/config/riscv/linux.h index 9060c940a44..c1cfa9bf28a 100644 --- a/gcc/config/riscv/linux.h +++ b/gcc/config/riscv/linux.h @@ -61,6 +61,8 @@ along with GCC; see the file COPYING3. If not see -dynamic-linker " GNU_USER_DYNAMIC_LINKER "}} \ %{static:-static} %{static-pie:-static -pie --no-dynamic-linker -z text}}" +#define TARGET_ASM_FILE_END riscv_file_end_indicate_exec_stack + #define STARTFILE_PREFIX_SPEC \ "/lib" XLEN_SPEC "/" ABI_SPEC "/ " \ "/usr/lib" XLEN_SPEC "/" ABI_SPEC "/ " \ diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index 4afb0b95839..fa4a706bf56 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_indicate_exec_stack () +{ + 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. */ 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) From patchwork Wed Jan 15 07:53:47 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Monk Chiang X-Patchwork-Id: 104810 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 6FB6A385DC0D for ; Wed, 15 Jan 2025 08:01:58 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 6FB6A385DC0D Authentication-Results: sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=sifive.com header.i=@sifive.com header.a=rsa-sha256 header.s=google header.b=NEGQc72E X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-pj1-x102d.google.com (mail-pj1-x102d.google.com [IPv6:2607:f8b0:4864:20::102d]) by sourceware.org (Postfix) with ESMTPS id 75DA73854836 for ; Wed, 15 Jan 2025 07:54:04 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 75DA73854836 Authentication-Results: sourceware.org; dmarc=pass (p=reject dis=none) header.from=sifive.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=sifive.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 75DA73854836 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::102d ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1736927644; cv=none; b=pXRIXJoWC78c9Q8F7OapAmJm2IG2o9A4SPsE1kfX8KSc9iBRCy/Ke3PGiEFD2cy8Yd9BcU5obYIAU6Wtjvs5r0D70Tdsl5eJI9Hx60XkDhC9atPIxdbBwbug05+ioHSpPIsDjEHFeFuLVbvK7UTLgu3HefPYrS+4/U28cHGQswk= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1736927644; c=relaxed/simple; bh=+iK1YGLgWiU2UYdPE8a1BRxfsI/88XuDABCyuJTUYbI=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=FxVlJb06B8RGmFzm6IGKn2HOOAV+OXGbEuNZMnf4BTjDo966bTcwKbNnismsABJfDRyZwhMTNkR3yzwOMFjaVb6acLyxrIWgUAz6qvU+iEyHQcddLidHWE9487R0AteqWJL0QGp/ceq1e48j90Gx+3ZVwToKEImXeo1lLe6mz0A= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 75DA73854836 Received: by mail-pj1-x102d.google.com with SMTP id 98e67ed59e1d1-2efded08c79so8515484a91.0 for ; Tue, 14 Jan 2025 23:54:04 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sifive.com; s=google; t=1736927643; x=1737532443; darn=gcc.gnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=XPpIdErRTiY9tX4MjgcAXnTjEcAcrF72uylGBBuZGj8=; b=NEGQc72EnM535WlljH2ubQLTXHXRpSqNhJL4064Kxdn+9k+r8Qig8PHYhcOdOmiVJ2 WY2RXdak+1BiWkBs3hOQuYkcsXLz+m3+LlTkY0KdcaJtAUVtUJT2VmKPXy1WYIiauO7U z1aRkT0CqYmJVmy1SY/PR952s9yVNGbkIK5LS0D66hjtUSmvpHLF8aA1U8oLsKbM4DEb 17VqGXLCNRRnJKyYQse1iyzh3ZRvm67x9rDxhac3hHOZCWw/ldsHy1L15Z9k126jQb+I tpIh+p+UxGQBNKKQD2CiIP/EOd0n3FcIlYZuWWWzQ/0IOti21vwXlSljdpO8CE99q6KM ahAA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1736927643; x=1737532443; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=XPpIdErRTiY9tX4MjgcAXnTjEcAcrF72uylGBBuZGj8=; b=uJTfx2owBv/KosS8Q+apKtGor619Wd+Xt9cc/V6eSDpiZqcSuVTiGaw3xYh5SQEXmw vtx0HO+zBCblxoOys7su20JyN7NSwZNsddyotSyErwgsbiWKA6Gwp2fRmP4KEr/bXqQV lFugsfrS5/xLFrbJvDHXettu80XHetK7oUq8aWVBeA/TWIqXecehE65OyCeTMJ0RCANc lah/ppeaLqz83tNgGaN/hZItLv8IG7kTnI3j5jzpqPIrdDcIusnXtd9gs+62uafumwnm esk3/ygqomLZ1GIBma2wRh/66I1fSJIV6/q9PvgawqCF+Jvc7iSTYlhHDVt7syo3IGMR fxWg== X-Gm-Message-State: AOJu0YxrZeQOJe7tdtJZe4pXbNvftNBNuF7Fg75n3dceOI8wz+MLyRn9 KnkjjxI3xZ1dNolK2nQdTirIPEfGvFC3xyMeVfghsCUOAnloNdoTTYZfO14JIAMahCdctMhU/wv gW1FFwEaaDUHoUGSqZm9crmX4iLw85KHQgS0Jn6ljgMRETK2X7A6WZjerC3y9hW9MhP/qGa3Vfh eamvrL9PrZZ78zinl1CseGnJosRiAsoP3suTRgbGHmxA== X-Gm-Gg: ASbGnctJBt5BQsxLHH47VgOWMhkZPySCUakUtvEj8MSjIRnNavU/uDLFUxLeRLCfeFd 9jtQEYU0sKb5EQy8tkxUeacsD/tOzu++mvrhp63H9w/SJGI+HdnHm66CAQyZPxOMxYzcWIbs2FC CAi2JcM6EXSS9NJ3y1B41j4Dm5GIXELy0O3zrf0zvpG2e0hXbDf/rsHnyD5ytL9Dkw8L7+Zlis4 Xpr4Ir/ApDuIrbNS4h/TSjke6xlyqywZx0b2Wnc96q4xfyzufI8loJMvPR/nlOetVhBvqS4cmjb w4HnGBkK X-Google-Smtp-Source: AGHT+IGqkwut2UbTFJAMpUqWImwoUwwF/O8A8n9Hl4+KYaQkTXz14UOegNooHyuLU1IG2W4EaInRqQ== X-Received: by 2002:a17:90b:51c5:b0:2f4:423a:8fb2 with SMTP id 98e67ed59e1d1-2f548eca27emr40536671a91.20.1736927642954; Tue, 14 Jan 2025 23:54:02 -0800 (PST) Received: from hsinchu02.internal.sifive.com ([210.176.154.34]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2f72c19a5d4sm839877a91.17.2025.01.14.23.54.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 14 Jan 2025 23:54:02 -0800 (PST) From: Monk Chiang To: gcc-patches@gcc.gnu.org, kito@gcc.gnu.org Cc: Monk Chiang Subject: [PATCH v3 4/4] RISC-V: Add -fcf-protection=[full|branch|return] to enable zicfiss, zicfilp. Date: Wed, 15 Jan 2025 15:53:47 +0800 Message-ID: <20250115075347.61344-4-monk.chiang@sifive.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250115075347.61344-1-monk.chiang@sifive.com> References: <20250115075347.61344-1-monk.chiang@sifive.com> MIME-Version: 1.0 X-Spam-Status: No, score=-12.6 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP, URIBL_BLACK autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces~patchwork=sourceware.org@gcc.gnu.org gcc/ChangeLog: * gcc/config/riscv/riscv.cc (is_zicfilp_p): New function. (is_zicfiss_p): New function. * gcc/config/riscv/riscv-zicfilp.cc: Update. * gcc/config/riscv/riscv.h: Update. * gcc/config/riscv/riscv.md: Update. gcc/testsuite/ChangeLog: * gcc/testsuite/c-c++-common/fcf-protection-1.c: Update. * gcc/testsuite/c-c++-common/fcf-protection-2.c: Update. * gcc/testsuite/c-c++-common/fcf-protection-3.c: Update. * gcc/testsuite/c-c++-common/fcf-protection-4.c: Update. * gcc/testsuite/c-c++-common/fcf-protection-5.c: Update. * gcc/testsuite/c-c++-common/fcf-protection-6.c: Update. * gcc/testsuite/c-c++-common/fcf-protection-7.c: Update. * gcc/testsuite/gcc.target/riscv/ssp-1.c: Update. * gcc/testsuite/gcc.target/riscv/ssp-2.c: Update. * gcc/testsuite/gcc.target/riscv/zicfilp-call.c: Update. * gcc/testsuite/gcc.target/riscv/interrupt-no-lpad.c: Update. --- 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.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 +- 15 files changed, 63 insertions(+), 24 deletions(-) diff --git a/gcc/config/riscv/riscv-zicfilp.cc b/gcc/config/riscv/riscv-zicfilp.cc index b30869ae297..4ded9032ea5 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 fa4a706bf56..7f5ef7dae34 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 @@ -10341,10 +10341,10 @@ riscv_file_end_indicate_exec_stack () 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) @@ -10404,7 +10404,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. */ @@ -10631,6 +10631,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. */ @@ -10925,7 +10939,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); @@ -10953,7 +10967,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); @@ -11015,7 +11029,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 @@ -11045,7 +11059,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) @@ -13960,9 +13974,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 073b9e4f2bd..2bcabd03517 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 5b4c81bb9e0..d626a350ee4 100644 --- a/gcc/config/riscv/riscv.md +++ b/gcc/config/riscv/riscv.md @@ -3716,11 +3716,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) @@ -3748,7 +3748,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]); @@ -3771,7 +3771,7 @@ (define_insn "tablejump" [(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")]) @@ -3779,7 +3779,7 @@ (define_insn "tablejump_cfi" [(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 f59a8fbdfdc..cc30c921a16 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 61059725af6..e318989f290 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 257e944c4a6..dd60017dde0 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 af4fc0b2812..2bde6e1e767 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 dc317f84b07..8c675c5f483 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 61059725af6..e318989f290 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 257e944c4a6..dd60017dde0 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 ff512b98c61..1290b373f08 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 abf47ec6442..24e3010c3cc 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 7c6098357e9..9d3d6b27038 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 75c8b32faa3..eb9e1468e7f 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);