Richard Earnshaw <richard.earns...@foss.arm.com> writes: > 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] >> <https://community.arm.com/developer/ip-products/processors/b/processors-ip-blog/posts/armv8-1-m-pointer-authentication-and-branch-target-identification-extension> >> >> gcc/Changelog >> >> 2021-11-03 Andrea Corallo <andrea.cora...@arm.com> >> >> * 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 <andrea.cora...@arm.com> >> >> * 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?
Yep > + 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. Ack. > +/* 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. Ack. > @@ -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. Okay. > + "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)? We have gcc/testsuite/gcc.target/arm/pac-7.c added by this patch. > R. Andrea