From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by sourceware.org (Postfix) with ESMTP id 7B0103856DC0 for ; Fri, 21 Oct 2022 12:58:16 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 7B0103856DC0 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=foss.arm.com Authentication-Results: sourceware.org; spf=none smtp.mailfrom=foss.arm.com Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 6AB741042; Fri, 21 Oct 2022 05:58:22 -0700 (PDT) Received: from [10.57.35.253] (unknown [10.57.35.253]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 2706A3F792; Fri, 21 Oct 2022 05:58:15 -0700 (PDT) Message-ID: Date: Fri, 21 Oct 2022 13:58:13 +0100 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.2.2 Subject: Re: [PATCH 10/15 V2] arm: Implement cortex-M return signing address codegen Content-Language: en-GB To: Andrea Corallo , Andrea Corallo via Gcc-patches Cc: Richard Earnshaw , nd References: From: Richard Earnshaw In-Reply-To: Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit X-Spam-Status: No, score=-3490.4 required=5.0 tests=BAYES_00,KAM_DMARC_STATUS,KAM_LAZY_DOMAIN_SECURITY,KAM_SHORT,NICE_REPLY_A,RCVD_IN_DNSWL_LOW,SPF_HELO_NONE,SPF_NONE,TXREP autolearn=no autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: On 14/09/2022 15:20, Andrea Corallo via Gcc-patches wrote: > Hi all, > > this patch enables address return signature and verification based on > Armv8.1-M Pointer Authentication [1]. > > To sign the return address, we use the PAC R12, LR, SP instruction > upon function entry. This is signing LR using SP and storing the > result in R12. R12 will be pushed into the stack. > > During function epilogue R12 will be popped and AUT R12, LR, SP will > be used to verify that the content of LR is still valid before return. > > Here an example of PAC instrumented function prologue and epilogue: > > void foo (void); > > int main() > { > foo (); > return 0; > } > > Compiled with '-march=armv8.1-m.main -mbranch-protection=pac-ret > -mthumb' translates into: > > main: > pac ip, lr, sp > push {r3, r7, ip, lr} > add r7, sp, #0 > bl foo > movs r3, #0 > mov r0, r3 > pop {r3, r7, ip, lr} > aut ip, lr, sp > bx lr > > The patch also takes care of generating a PACBTI instruction in place > of the sequence BTI+PAC when Branch Target Identification is enabled > contextually. > > Ex. the previous example compiled with '-march=armv8.1-m.main > -mbranch-protection=pac-ret+bti -mthumb' translates into: > > main: > pacbti ip, lr, sp > push {r3, r7, ip, lr} > add r7, sp, #0 > bl foo > movs r3, #0 > mov r0, r3 > pop {r3, r7, ip, lr} > aut ip, lr, sp > bx lr > > As part of previous upstream suggestions a test for varargs has been > added and '-mtpcs-frame' is deemed being incompatible with this return > signing address feature being introduced. > > [1] > > gcc/Changelog > > 2021-11-03 Andrea Corallo > > * config/arm/arm.c: (arm_compute_frame_layout) > (arm_expand_prologue, thumb2_expand_return, arm_expand_epilogue) > (arm_conditional_register_usage): Update for pac codegen. > (arm_current_function_pac_enabled_p): New function. > * config/arm/arm.md (pac_ip_lr_sp, pacbti_ip_lr_sp, aut_ip_lr_sp): > Add new patterns. > * config/arm/unspecs.md (UNSPEC_PAC_IP_LR_SP) > (UNSPEC_PACBTI_IP_LR_SP, UNSPEC_AUT_IP_LR_SP): Add unspecs. > > gcc/testsuite/Changelog > > 2021-11-03 Andrea Corallo > > * gcc.target/arm/pac.h : New file. > * gcc.target/arm/pac-1.c : New test case. > * gcc.target/arm/pac-2.c : Likewise. > * gcc.target/arm/pac-3.c : Likewise. > * gcc.target/arm/pac-4.c : Likewise. > * gcc.target/arm/pac-5.c : Likewise. > * gcc.target/arm/pac-6.c : Likewise. > * gcc.target/arm/pac-7.c : Likewise. > * gcc.target/arm/pac-8.c : Likewise. > + if (arm_current_function_pac_enabled_p () && !(arm_arch7 && arm_arch_cmse)) + error ("This architecture does not support branch protection instructions"); This test feels wrong. What does having cmse give us? I suspect you want a test that ensures we have at least v8-m.main so that the NOP instructions are correctly defined as NOPs (or, in this case, PACBTI instructions) rather than unpredictable; but if that's the case then I think you really want to write the test that way here (perhaps in a macro) and then move this test into that so that it becomes self-documenting - but don't we have a v8-m.main test anyway? + if (arm_current_function_pac_enabled_p ()) + { + gcc_assert (!(saved_regs_mask & (1 << PC_REGNUM))); + arm_emit_multi_reg_pop (saved_regs_mask); + emit_insn (gen_aut_nop ()); + emit_jump_insn (simple_return_rtx); + } The assert is using indents that are just spaces, but the other lines use tabs. Please use tabs everywhere rather than mixing like this. +/* Return TRUE if return address signing mechanism is enabled. */ +bool +arm_current_function_pac_enabled_p (void) +{ + return aarch_ra_sign_scope == AARCH_FUNCTION_ALL + || (aarch_ra_sign_scope == AARCH_FUNCTION_NON_LEAF + && !crtl->is_leaf); +} This is a case where you should use parenthesis around the expression so that the continuation lines are correctly indented. @@ -11518,7 +11518,7 @@ (define_expand "prologue" arm_expand_prologue (); else thumb1_expand_prologue (); - DONE; + DONE; " ) Although this is a trivial cleanup, it has nothing to do with this patch. Please remove. + "arm_arch7 && arm_arch_cmse" See my comments earlier about this test; the same applies here. + (unspec:SI [(reg:SI SP_REGNUM) (reg:SI LR_REGNUM)] + UNSPEC_PAC_NOP))] + Again you have a mix of lines indented with tabs and lines indented with just spaces. Similarly with pacbti_nop and aut_nop. Do you have a test for the nested functions case (I can't see it, but perhaps I've missed it somewhere)? R.