Ping!! > -----Original Message----- > From: Gcc-patches <gcc-patches- > bounces+srinath.parvathaneni=arm....@gcc.gnu.org> On Behalf Of Srinath > Parvathaneni via Gcc-patches > Sent: 05 May 2022 12:02 > To: gcc-patches@gcc.gnu.org > Cc: Richard Earnshaw <richard.earns...@arm.com> > Subject: [PATCH v2][GCC] arm: Add support for dwarf debug directives and > pseudo hard-register for PAC feature. > > Hello, > > This patch teaches the DWARF support in gcc about RA_AUTH_CODE pseudo > hard-register and also .save {ra_auth_code} and .cfi_offset ra_auth_code > <offset> dwarf directives for the PAC feature in Armv8.1-M architecture. > > RA_AUTH_CODE register number is 107 and it's dwarf register number is 143. > > When compiled with " -march=armv8.1-m.main -mbranch-protection=pac- > ret+leaf+bti -mthumb -mfloat-abi=soft -fasynchronous-unwind-tables -g -O2 > -S" command line options, the assembly output after this patch looks like > below: > > ... > .cfi_startproc > pacbti ip, lr, sp > movs r1, #40 > push {ip, lr} > .save {ra_auth_code, lr} > .cfi_def_cfa_offset 8 > .cfi_offset 143, -8 > .cfi_offset 14, -4 > ... > pop {ip, lr} > .cfi_restore 14 > .cfi_restore 143 > .cfi_def_cfa_offset 0 > movs r0, #0 > aut ip, lr, sp > bx lr > .cfi_endproc > ... > > This patch can be committed after the patch at > https://gcc.gnu.org/pipermail/gcc-patches/2021-November/583407.html > is committed. > > Regression tested on arm-none-eabi target and found no regressions. > > Ok for master? > > Regards, > Srinath. > > gcc/ChangeLog: > > 2022-04-06 Srinath Parvathaneni <srinath.parvathan...@arm.com> > > * config/arm/aout.h (ra_auth_code): Add to enum. > * config/arm/arm.cc (emit_multi_reg_push): Add RA_AUTH_CODE > register to > dwarf frame expression. > (arm_emit_multi_reg_pop): Restore RA_AUTH_CODE register. > (arm_expand_prologue): Mark as frame related insn. > (arm_regno_class): Check for pac pseudo reigster. > (arm_dbx_register_number): Assign ra_auth_code register number in > dwarf. > (arm_unwind_emit_sequence): Print .save directive with ra_auth_code > register. > (arm_conditional_register_usage): Mark ra_auth_code in fixed > reigsters. > * config/arm/arm.h (FIRST_PSEUDO_REGISTER): Modify. > (IS_PAC_Pseudo_REGNUM): Define. > (enum reg_class): Add PAC_REG entry. > * config/arm/arm.md (RA_AUTH_CODE): Define. > > gcc/testsuite/ChangeLog: > > 2022-04-06 Srinath Parvathaneni <srinath.parvathan...@arm.com> > > * g++.target/arm/pac-1.C: New test. > * gcc.target/arm/pac-9.c: Likewise. > > > ############### Attachment also inlined for ease of reply > ############### > > > diff --git a/gcc/config/arm/aout.h b/gcc/config/arm/aout.h index > b918ad3782fbee82320febb8b6e72ad615780261..ffeed45a678f17c63d5b42c2 > 1f020ca416cbf23f 100644 > --- a/gcc/config/arm/aout.h > +++ b/gcc/config/arm/aout.h > @@ -74,7 +74,8 @@ > "wr8", "wr9", "wr10", "wr11", \ > "wr12", "wr13", "wr14", "wr15", \ > "wcgr0", "wcgr1", "wcgr2", "wcgr3", \ > - "cc", "vfpcc", "sfp", "afp", "apsrq", "apsrge", "p0" \ > + "cc", "vfpcc", "sfp", "afp", "apsrq", "apsrge", "p0", \ > + "ra_auth_code" \ > } > #endif > > diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h index > 3495ab857eac38ecdf37e55f1d201b1c35cbde0b..c77777067819f6785e44d30d > 8e5365505ab98682 100644 > --- a/gcc/config/arm/arm.h > +++ b/gcc/config/arm/arm.h > @@ -816,7 +816,8 @@ extern const int arm_arch_cde_coproc_bits[]; > s16-s31 S VFP variable (aka d8-d15). > vfpcc Not a real register. Represents the VFP condition > code flags. > - vpr Used to represent MVE VPR predication. */ > + vpr Used to represent MVE VPR predication. > + ra_auth_code Pseudo register to save PAC. */ > > /* The stack backtrace structure is as follows: > fp points to here: | save code pointer | [fp] > @@ -857,7 +858,7 @@ extern const int arm_arch_cde_coproc_bits[]; > 1,1,1,1,1,1,1,1, \ > 1,1,1,1, \ > /* Specials. */ \ > - 1,1,1,1,1,1,1 \ > + 1,1,1,1,1,1,1,1 \ > } > > /* 1 for registers not available across function calls. > @@ -887,7 +888,7 @@ extern const int arm_arch_cde_coproc_bits[]; > 1,1,1,1,1,1,1,1, \ > 1,1,1,1, \ > /* Specials. */ \ > - 1,1,1,1,1,1,1 \ > + 1,1,1,1,1,1,1,1 \ > } > > #ifndef SUBTARGET_CONDITIONAL_REGISTER_USAGE > @@ -1063,10 +1064,10 @@ extern const int arm_arch_cde_coproc_bits[]; > && (LAST_VFP_REGNUM - (REGNUM) >= 2 * (N) - 1)) > > /* The number of hard registers is 16 ARM + 1 CC + 1 SFP + 1 AFP > - + 1 APSRQ + 1 APSRGE + 1 VPR. */ > + + 1 APSRQ + 1 APSRGE + 1 VPR + 1 Pseudo register to save PAC. */ > /* Intel Wireless MMX Technology registers add 16 + 4 more. */ > /* VFP (VFP3) adds 32 (64) + 1 VFPCC. */ > -#define FIRST_PSEUDO_REGISTER 107 > +#define FIRST_PSEUDO_REGISTER 108 > > #define DBX_REGISTER_NUMBER(REGNO) arm_dbx_register_number > (REGNO) > > @@ -1253,12 +1254,15 @@ extern int arm_regs_in_sequence[]; > CC_REGNUM, VFPCC_REGNUM, \ > FRAME_POINTER_REGNUM, ARG_POINTER_REGNUM, \ > SP_REGNUM, PC_REGNUM, APSRQ_REGNUM, \ > - APSRGE_REGNUM, VPR_REGNUM \ > + APSRGE_REGNUM, VPR_REGNUM, RA_AUTH_CODE \ > } > > #define IS_VPR_REGNUM(REGNUM) \ > ((REGNUM) == VPR_REGNUM) > > +#define IS_PAC_Pseudo_REGNUM(REGNUM) \ > + ((REGNUM) == RA_AUTH_CODE) > + > /* Use different register alloc ordering for Thumb. */ #define > ADJUST_REG_ALLOC_ORDER arm_order_regs_for_local_alloc () > > @@ -1297,6 +1301,7 @@ enum reg_class > SFP_REG, > AFP_REG, > VPR_REG, > + PAC_REG, > GENERAL_AND_VPR_REGS, > ALL_REGS, > LIM_REG_CLASSES > @@ -1327,6 +1332,7 @@ enum reg_class > "SFP_REG", \ > "AFP_REG", \ > "VPR_REG", \ > + "PAC_REG", \ > "GENERAL_AND_VPR_REGS", \ > "ALL_REGS" \ > } > @@ -1356,6 +1362,7 @@ enum reg_class > { 0x00000000, 0x00000000, 0x00000000, 0x00000040 }, /* SFP_REG */ > \ > { 0x00000000, 0x00000000, 0x00000000, 0x00000080 }, /* AFP_REG */ > \ > { 0x00000000, 0x00000000, 0x00000000, 0x00000400 }, /* VPR_REG. */ > \ > + { 0x00000000, 0x00000000, 0x00000000, 0x00000800 }, /* PAC_REG. */ > \ > { 0x00005FFF, 0x00000000, 0x00000000, 0x00000400 }, /* > GENERAL_AND_VPR_REGS. */ \ > { 0xFFFF7FFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0000040F } /* ALL_REGS. */ > \ > } > diff --git a/gcc/config/arm/arm.cc b/gcc/config/arm/arm.cc index > a2b720a666077c528034c13e27d7c7168cb824d7..a14ea47badd8b90315376c2 > 7553e5894beeea990 100644 > --- a/gcc/config/arm/arm.cc > +++ b/gcc/config/arm/arm.cc > @@ -22151,7 +22151,9 @@ emit_multi_reg_push (unsigned long mask, > unsigned long dwarf_regs_mask) > { > if (mask & (1 << i)) > { > - reg = gen_rtx_REG (SImode, i); > + rtx reg1 = reg = gen_rtx_REG (SImode, i); > + if (arm_current_function_pac_enabled_p () && i == IP_REGNUM) > + reg1 = gen_rtx_REG (SImode, RA_AUTH_CODE); > > XVECEXP (par, 0, 0) > = gen_rtx_SET (gen_frame_mem > @@ -22168,8 +22170,12 @@ emit_multi_reg_push (unsigned long mask, > unsigned long dwarf_regs_mask) > > if (dwarf_regs_mask & (1 << i)) > { > + /* Only the first register in the multi push instruction is stored > + to frame memory here. > + Eg: push {r7 ,r8, ip, lr} > + Only r7 is stored to frame memory here. */ > tmp = gen_rtx_SET (gen_frame_mem (SImode, stack_pointer_rtx), > - reg); > + reg1); > RTX_FRAME_RELATED_P (tmp) = 1; > XVECEXP (dwarf, 0, dwarf_par_index++) = tmp; > } > @@ -22182,18 +22188,25 @@ emit_multi_reg_push (unsigned long mask, > unsigned long dwarf_regs_mask) > { > if (mask & (1 << i)) > { > - reg = gen_rtx_REG (SImode, i); > + rtx reg1 = reg = gen_rtx_REG (SImode, i); > + if (arm_current_function_pac_enabled_p () && i == IP_REGNUM) > + reg1 = gen_rtx_REG (SImode, RA_AUTH_CODE); > > XVECEXP (par, 0, j) = gen_rtx_USE (VOIDmode, reg); > > if (dwarf_regs_mask & (1 << i)) > { > + /* Except the first register in the multi push instruction all the > + remaining registers are stored to frame memory here. > + Eg: push {r7, r8, ip, lr} > + r8, ip (ra_auth_code in case PACBTI enabled) and lr registers > + are stored to frame memory here. */ > tmp > = gen_rtx_SET (gen_frame_mem > (SImode, > plus_constant (Pmode, stack_pointer_rtx, > 4 * j)), > - reg); > + reg1); > RTX_FRAME_RELATED_P (tmp) = 1; > XVECEXP (dwarf, 0, dwarf_par_index++) = tmp; > } > @@ -22278,7 +22291,9 @@ arm_emit_multi_reg_pop (unsigned long > saved_regs_mask) > for (j = 0, i = 0; j < num_regs; i++) > if (saved_regs_mask & (1 << i)) > { > - reg = gen_rtx_REG (SImode, i); > + rtx reg1 = reg = gen_rtx_REG (SImode, i); > + if (arm_current_function_pac_enabled_p () && i == IP_REGNUM) > + reg1 = gen_rtx_REG (SImode, RA_AUTH_CODE); > if ((num_regs == 1) && emit_update && !return_in_pc) > { > /* Emit single load with writeback. */ @@ -22286,7 +22301,7 @@ > arm_emit_multi_reg_pop (unsigned long saved_regs_mask) > gen_rtx_POST_INC (Pmode, > stack_pointer_rtx)); > tmp = emit_insn (gen_rtx_SET (reg, tmp)); > - REG_NOTES (tmp) = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf); > + REG_NOTES (tmp) = alloc_reg_note (REG_CFA_RESTORE, reg1, > dwarf); > return; > } > > @@ -22300,7 +22315,7 @@ arm_emit_multi_reg_pop (unsigned long > saved_regs_mask) > /* We need to maintain a sequence for DWARF info too. As dwarf info > should not have PC, skip PC. */ > if (i != PC_REGNUM) > - dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf); > + dwarf = alloc_reg_note (REG_CFA_RESTORE, reg1, dwarf); > > j++; > } > @@ -25585,6 +25600,9 @@ arm_regno_class (int regno) > if (IS_VPR_REGNUM (regno)) > return VPR_REG; > > + if (IS_PAC_Pseudo_REGNUM (regno)) > + return PAC_REG; > + > if (TARGET_THUMB1) > { > if (regno == STACK_POINTER_REGNUM) @@ -29557,6 +29575,9 @@ > arm_dbx_register_number (unsigned int regno) > if (IS_IWMMXT_REGNUM (regno)) > return 112 + regno - FIRST_IWMMXT_REGNUM; > > + if (IS_PAC_Pseudo_REGNUM (regno)) > + return 143; > + > return DWARF_FRAME_REGISTERS; > } > > @@ -29678,6 +29699,11 @@ arm_unwind_emit_sequence (FILE * out_file, > rtx p) > reg_size = 8; > fprintf (out_file, "\t.vsave {"); > } > + else if (IS_PAC_Pseudo_REGNUM (reg)) > + { > + reg_size = 4; > + fprintf (out_file, "\t.save {"); > + } > else > /* Unknown register type. */ > gcc_unreachable (); > @@ -29707,6 +29733,8 @@ arm_unwind_emit_sequence (FILE * out_file, rtx > p) > double precision register names. */ > if (IS_VFP_REGNUM (reg)) > asm_fprintf (out_file, "d%d", (reg - FIRST_VFP_REGNUM) / 2); > + else if (IS_PAC_Pseudo_REGNUM (reg)) > + asm_fprintf (asm_out_file, "ra_auth_code"); > else > asm_fprintf (out_file, "%r", reg); > > @@ -30575,7 +30603,10 @@ arm_conditional_register_usage (void) > } > > if (TARGET_HAVE_PACBTI) > - call_used_regs[IP_REGNUM] = 1; > + { > + call_used_regs[IP_REGNUM] = 1; > + fixed_regs[RA_AUTH_CODE] = 0; > + } > > /* The Q and GE bits are only accessed via special ACLE patterns. */ > CLEAR_HARD_REG_BIT (operand_reg_set, APSRQ_REGNUM); diff --git > a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index > 2221bc68f358f277eff176b7abab5adf1e952399..aaaf13574593846d02655d59 > 3d45d751a5b7512e 100644 > --- a/gcc/config/arm/arm.md > +++ b/gcc/config/arm/arm.md > @@ -42,6 +42,7 @@ > (APSRQ_REGNUM 104) ; Q bit pseudo register > (APSRGE_REGNUM 105) ; GE bits pseudo register > (VPR_REGNUM 106) ; Vector Predication Register - MVE register. > + (RA_AUTH_CODE 107) ; Pseudo register to save PAC. > ] > ) > ;; 3rd operand to select_dominance_cc_mode diff --git > a/gcc/testsuite/g++.target/arm/pac-1.C b/gcc/testsuite/g++.target/arm/pac- > 1.C > new file mode 100644 > index > 0000000000000000000000000000000000000000..b447213ab4e1b72cacd483e > fece077fbbca3a608 > --- /dev/null > +++ b/gcc/testsuite/g++.target/arm/pac-1.C > @@ -0,0 +1,33 @@ > +/* Check that GCC does .save and .cfi_offset directives with > +RA_AUTH_CODE pseudo hard-register. */ > +/* { dg-do compile } */ > +/* { dg-skip-if "avoid conflicting multilib options" { *-*-* } { > +"-marm" "-mcpu=*" } } */ > +/* { dg-options "-march=armv8.1-m.main > +-mbranch-protection=pac-ret+leaf+bti -mthumb -mfloat-abi=soft > +--save-temps -g" } */ > + > +__attribute__((noinline)) void > +fn1 (int a, int b, int c) > +{ > + if (a != b + c) > + __builtin_abort (); > + else > + throw b+c; > +} > + > +int main () > +{ > + int a = 120; > + try > + { > + fn1 (a, 40, 80); > + } > + catch (int x) > + { > + if (x != a) > + __builtin_abort (); > + else > + return 0; > + } > +} > + > +/* { dg-final { scan-assembler "\.save \{r7, ra_auth_code, lr\}" } } */ > +/* { dg-final { scan-assembler "\.save \{r4, r7, ra_auth_code, lr\}" } > +} */ > +/* { dg-final { scan-assembler "\.cfi_offset 143, \-8" } } */ > diff --git a/gcc/testsuite/gcc.target/arm/pac-9.c > b/gcc/testsuite/gcc.target/arm/pac-9.c > new file mode 100644 > index > 0000000000000000000000000000000000000000..2a69db6e8e8a32090a6c16c > cc66871946188f8d8 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/arm/pac-9.c > @@ -0,0 +1,21 @@ > +/* Check that GCC does .save and .cfi_offset directives with > +RA_AUTH_CODE pseudo hard-register. */ > +/* { dg-do compile } */ > +/* { dg-skip-if "avoid conflicting multilib options" { *-*-* } { > +"-marm" "-mcpu=*" } } */ > +/* { dg-options "-march=armv8.1-m.main > +-mbranch-protection=pac-ret+leaf+bti -mthumb -mfloat-abi=soft > +-fasynchronous-unwind-tables --save-temps -g" } */ > + > +__attribute__((noinline)) void > +fn1 (int a, int b, int c) > +{ > + if (a != b + c) > + __builtin_abort (); > +} > + > +int main () > +{ > + fn1 (40, 40, 80); > + return 0; > +} > + > +/* { dg-final { scan-assembler "\.save \{r7, ra_auth_code, lr\}" } } */ > +/* { dg-final { scan-assembler "\.save \{r3, r7, ra_auth_code, lr\}" } > +} */ > +/* { dg-final { scan-assembler "\.cfi_offset 143, \-8" } } */
RE: [PATCH v2][GCC] arm: Add support for dwarf debug directives and pseudo hard-register for PAC feature.
Srinath Parvathaneni via Gcc-patches Mon, 04 Jul 2022 11:33:40 -0700