* [PATCH v2][GCC] arm: Add support for dwarf debug directives and pseudo hard-register for PAC feature.
@ 2022-05-05 11:02 Srinath Parvathaneni
2022-07-04 18:33 ` Srinath Parvathaneni
0 siblings, 1 reply; 5+ messages in thread
From: Srinath Parvathaneni @ 2022-05-05 11:02 UTC (permalink / raw)
To: gcc-patches; +Cc: Kyrylo.Tkachov, Richard.Earnshaw
[-- Attachment #1: Type: text/plain, Size: 13434 bytes --]
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.parvathaneni@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.parvathaneni@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..ffeed45a678f17c63d5b42c21f020ca416cbf23f 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..c77777067819f6785e44d30d8e5365505ab98682 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..a14ea47badd8b90315376c27553e5894beeea990 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..aaaf13574593846d02655d593d45d751a5b7512e 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..b447213ab4e1b72cacd483efece077fbbca3a608
--- /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..2a69db6e8e8a32090a6c16ccc66871946188f8d8
--- /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" } } */
[-- Attachment #2: rb14831.patch --]
[-- Type: text/plain, Size: 11076 bytes --]
diff --git a/gcc/config/arm/aout.h b/gcc/config/arm/aout.h
index b918ad3782fbee82320febb8b6e72ad615780261..ffeed45a678f17c63d5b42c21f020ca416cbf23f 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..c77777067819f6785e44d30d8e5365505ab98682 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..a14ea47badd8b90315376c27553e5894beeea990 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..aaaf13574593846d02655d593d45d751a5b7512e 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..b447213ab4e1b72cacd483efece077fbbca3a608
--- /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..2a69db6e8e8a32090a6c16ccc66871946188f8d8
--- /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" } } */
^ permalink raw reply [flat|nested] 5+ messages in thread
* RE: [PATCH v2][GCC] arm: Add support for dwarf debug directives and pseudo hard-register for PAC feature.
2022-05-05 11:02 [PATCH v2][GCC] arm: Add support for dwarf debug directives and pseudo hard-register for PAC feature Srinath Parvathaneni
@ 2022-07-04 18:33 ` Srinath Parvathaneni
0 siblings, 0 replies; 5+ messages in thread
From: Srinath Parvathaneni @ 2022-07-04 18:33 UTC (permalink / raw)
To: gcc-patches, Richard Earnshaw
Ping!!
> -----Original Message-----
> From: Gcc-patches <gcc-patches-
> bounces+srinath.parvathaneni=arm.com@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.Earnshaw@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.parvathaneni@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.parvathaneni@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" } } */
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v2][GCC] arm: Add support for dwarf debug directives and pseudo hard-register for PAC feature.
@ 2021-11-12 18:02 Srinath Parvathaneni
2021-12-13 10:44 ` Srinath Parvathaneni
0 siblings, 1 reply; 5+ messages in thread
From: Srinath Parvathaneni @ 2021-11-12 18:02 UTC (permalink / raw)
To: gcc-patches; +Cc: Kyrylo.Tkachov, Richard.Earnshaw, Tejas.Belagod
[-- Attachment #1: Type: text/plain, Size: 9673 bytes --]
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 "arm-none-eabi-gcc -O2 -mthumb -march=armv8.1-m.main+pacbti -S -fasynchronous-unwind-tables -g"
command line options, the directives supported in this patch looks like below:
...
push {ip}
.save {ra_auth_code}
.cfi_def_cfa_offset 8
.cfi_offset 143, -8
...
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:
2021-11-12 Srinath Parvathaneni <srinath.parvathaneni@arm.com>
* config/arm/aout.h (ra_auth_code): Add to enum.
* config/arm/arm.c (emit_multi_reg_push): Add RA_AUTH_CODE register to
dwarf frame expression instead of IP_REGNUM.
(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:
2021-11-12 Srinath Parvathaneni <srinath.parvathaneni@arm.com>
* g++.target/arm/pac-1.C: New test.
############### Attachment also inlined for ease of reply ###############
diff --git a/gcc/config/arm/aout.h b/gcc/config/arm/aout.h
index 25a2812a663742893b928398b0d3948e97f1905b..c69e299e012f46c8d0711830125dbf2f6b2e93d7 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 8e6ef41f6b065217d1af3f4f1cb85b2d8fbd0dc0..f31944e85c9ab83501f156d138e2aea1bcb5b79d 100644
--- a/gcc/config/arm/arm.h
+++ b/gcc/config/arm/arm.h
@@ -815,7 +815,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]
@@ -856,7 +857,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.
@@ -886,7 +887,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
@@ -1062,10 +1063,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)
@@ -1248,12 +1249,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 ()
@@ -1292,6 +1296,7 @@ enum reg_class
SFP_REG,
AFP_REG,
VPR_REG,
+ PAC_REG,
ALL_REGS,
LIM_REG_CLASSES
};
@@ -1321,6 +1326,7 @@ enum reg_class
"SFP_REG", \
"AFP_REG", \
"VPR_REG", \
+ "PAC_REG", \
"ALL_REGS" \
}
@@ -1349,6 +1355,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. */ \
{ 0xFFFF7FFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0000000F } /* ALL_REGS. */ \
}
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index a3e34747ba52840bd82f76df4a3f05704bd42ec1..966c49a3bf21de909dbab5abcac5d1d3b2af4262 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -22000,7 +22000,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_pac_enabled_for_curr_function_p () && i == IP_REGNUM)
+ reg1 = gen_rtx_REG (SImode, RA_AUTH_CODE);
XVECEXP (par, 0, 0)
= gen_rtx_SET (gen_frame_mem
@@ -22018,7 +22020,7 @@ emit_multi_reg_push (unsigned long mask, unsigned long dwarf_regs_mask)
if (dwarf_regs_mask & (1 << i))
{
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;
}
@@ -23505,7 +23507,10 @@ arm_expand_prologue (void)
saved_regs += arm_save_coproc_regs ();
if (arm_pac_enabled_for_curr_function_p ())
- emit_multi_reg_push (1 << IP_REGNUM, 1 << IP_REGNUM);
+ {
+ insn = emit_multi_reg_push (1 << IP_REGNUM, 1 << IP_REGNUM);
+ RTX_FRAME_RELATED_P (insn) = 1;
+ }
if (frame_pointer_needed && TARGET_ARM)
{
@@ -25435,6 +25440,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)
@@ -29429,6 +29437,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;
}
@@ -29550,6 +29561,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 ();
@@ -29579,6 +29595,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);
@@ -30447,7 +30465,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 564170dc4500c2c5d961c9a19dd86a31416dc965..f27dc3f9041d8b32e7ad750c39143a6764156fe9 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..d33c860f1e368581dd9c3552a7201c7932b8560f
--- /dev/null
+++ b/gcc/testsuite/g++.target/arm/pac-1.C
@@ -0,0 +1,32 @@
+/* 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 "-O2 -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 \{ra_auth_code\}" } } */
+/* { dg-final { scan-assembler "\.cfi_offset 143, \-8" } } */
[-- Attachment #2: rb14831.patch --]
[-- Type: text/plain, Size: 7746 bytes --]
diff --git a/gcc/config/arm/aout.h b/gcc/config/arm/aout.h
index 25a2812a663742893b928398b0d3948e97f1905b..c69e299e012f46c8d0711830125dbf2f6b2e93d7 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 8e6ef41f6b065217d1af3f4f1cb85b2d8fbd0dc0..f31944e85c9ab83501f156d138e2aea1bcb5b79d 100644
--- a/gcc/config/arm/arm.h
+++ b/gcc/config/arm/arm.h
@@ -815,7 +815,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]
@@ -856,7 +857,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.
@@ -886,7 +887,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
@@ -1062,10 +1063,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)
@@ -1248,12 +1249,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 ()
@@ -1292,6 +1296,7 @@ enum reg_class
SFP_REG,
AFP_REG,
VPR_REG,
+ PAC_REG,
ALL_REGS,
LIM_REG_CLASSES
};
@@ -1321,6 +1326,7 @@ enum reg_class
"SFP_REG", \
"AFP_REG", \
"VPR_REG", \
+ "PAC_REG", \
"ALL_REGS" \
}
@@ -1349,6 +1355,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. */ \
{ 0xFFFF7FFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0000000F } /* ALL_REGS. */ \
}
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index a3e34747ba52840bd82f76df4a3f05704bd42ec1..966c49a3bf21de909dbab5abcac5d1d3b2af4262 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -22000,7 +22000,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_pac_enabled_for_curr_function_p () && i == IP_REGNUM)
+ reg1 = gen_rtx_REG (SImode, RA_AUTH_CODE);
XVECEXP (par, 0, 0)
= gen_rtx_SET (gen_frame_mem
@@ -22018,7 +22020,7 @@ emit_multi_reg_push (unsigned long mask, unsigned long dwarf_regs_mask)
if (dwarf_regs_mask & (1 << i))
{
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;
}
@@ -23505,7 +23507,10 @@ arm_expand_prologue (void)
saved_regs += arm_save_coproc_regs ();
if (arm_pac_enabled_for_curr_function_p ())
- emit_multi_reg_push (1 << IP_REGNUM, 1 << IP_REGNUM);
+ {
+ insn = emit_multi_reg_push (1 << IP_REGNUM, 1 << IP_REGNUM);
+ RTX_FRAME_RELATED_P (insn) = 1;
+ }
if (frame_pointer_needed && TARGET_ARM)
{
@@ -25435,6 +25440,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)
@@ -29429,6 +29437,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;
}
@@ -29550,6 +29561,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 ();
@@ -29579,6 +29595,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);
@@ -30447,7 +30465,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 564170dc4500c2c5d961c9a19dd86a31416dc965..f27dc3f9041d8b32e7ad750c39143a6764156fe9 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..d33c860f1e368581dd9c3552a7201c7932b8560f
--- /dev/null
+++ b/gcc/testsuite/g++.target/arm/pac-1.C
@@ -0,0 +1,32 @@
+/* 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 "-O2 -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 \{ra_auth_code\}" } } */
+/* { dg-final { scan-assembler "\.cfi_offset 143, \-8" } } */
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH v2][GCC] arm: Add support for dwarf debug directives and pseudo hard-register for PAC feature.
2021-11-12 18:02 Srinath Parvathaneni
@ 2021-12-13 10:44 ` Srinath Parvathaneni
2022-01-12 13:45 ` Srinath Parvathaneni
0 siblings, 1 reply; 5+ messages in thread
From: Srinath Parvathaneni @ 2021-12-13 10:44 UTC (permalink / raw)
To: gcc-patches; +Cc: Kyrylo Tkachov, Richard Earnshaw, Tejas Belagod
Ping!!
________________________________
From: Srinath Parvathaneni
Sent: 12 November 2021 18:03
To: gcc-patches@gcc.gnu.org <gcc-patches@gcc.gnu.org>
Cc: Kyrylo Tkachov <Kyrylo.Tkachov@arm.com>; Richard Earnshaw <Richard.Earnshaw@arm.com>; Tejas Belagod <Tejas.Belagod@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 "arm-none-eabi-gcc -O2 -mthumb -march=armv8.1-m.main+pacbti -S -fasynchronous-unwind-tables -g"
command line options, the directives supported in this patch looks like below:
...
push {ip}
.save {ra_auth_code}
.cfi_def_cfa_offset 8
.cfi_offset 143, -8
...
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:
2021-11-12 Srinath Parvathaneni <srinath.parvathaneni@arm.com>
* config/arm/aout.h (ra_auth_code): Add to enum.
* config/arm/arm.c (emit_multi_reg_push): Add RA_AUTH_CODE register to
dwarf frame expression instead of IP_REGNUM.
(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:
2021-11-12 Srinath Parvathaneni <srinath.parvathaneni@arm.com>
* g++.target/arm/pac-1.C: New test.
############### Attachment also inlined for ease of reply ###############
diff --git a/gcc/config/arm/aout.h b/gcc/config/arm/aout.h
index 25a2812a663742893b928398b0d3948e97f1905b..c69e299e012f46c8d0711830125dbf2f6b2e93d7 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 8e6ef41f6b065217d1af3f4f1cb85b2d8fbd0dc0..f31944e85c9ab83501f156d138e2aea1bcb5b79d 100644
--- a/gcc/config/arm/arm.h
+++ b/gcc/config/arm/arm.h
@@ -815,7 +815,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]
@@ -856,7 +857,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.
@@ -886,7 +887,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
@@ -1062,10 +1063,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)
@@ -1248,12 +1249,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 ()
@@ -1292,6 +1296,7 @@ enum reg_class
SFP_REG,
AFP_REG,
VPR_REG,
+ PAC_REG,
ALL_REGS,
LIM_REG_CLASSES
};
@@ -1321,6 +1326,7 @@ enum reg_class
"SFP_REG", \
"AFP_REG", \
"VPR_REG", \
+ "PAC_REG", \
"ALL_REGS" \
}
@@ -1349,6 +1355,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. */ \
{ 0xFFFF7FFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0000000F } /* ALL_REGS. */ \
}
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index a3e34747ba52840bd82f76df4a3f05704bd42ec1..966c49a3bf21de909dbab5abcac5d1d3b2af4262 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -22000,7 +22000,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_pac_enabled_for_curr_function_p () && i == IP_REGNUM)
+ reg1 = gen_rtx_REG (SImode, RA_AUTH_CODE);
XVECEXP (par, 0, 0)
= gen_rtx_SET (gen_frame_mem
@@ -22018,7 +22020,7 @@ emit_multi_reg_push (unsigned long mask, unsigned long dwarf_regs_mask)
if (dwarf_regs_mask & (1 << i))
{
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;
}
@@ -23505,7 +23507,10 @@ arm_expand_prologue (void)
saved_regs += arm_save_coproc_regs ();
if (arm_pac_enabled_for_curr_function_p ())
- emit_multi_reg_push (1 << IP_REGNUM, 1 << IP_REGNUM);
+ {
+ insn = emit_multi_reg_push (1 << IP_REGNUM, 1 << IP_REGNUM);
+ RTX_FRAME_RELATED_P (insn) = 1;
+ }
if (frame_pointer_needed && TARGET_ARM)
{
@@ -25435,6 +25440,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)
@@ -29429,6 +29437,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;
}
@@ -29550,6 +29561,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 ();
@@ -29579,6 +29595,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);
@@ -30447,7 +30465,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 564170dc4500c2c5d961c9a19dd86a31416dc965..f27dc3f9041d8b32e7ad750c39143a6764156fe9 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..d33c860f1e368581dd9c3552a7201c7932b8560f
--- /dev/null
+++ b/gcc/testsuite/g++.target/arm/pac-1.C
@@ -0,0 +1,32 @@
+/* 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 "-O2 -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 \{ra_auth_code\}" } } */
+/* { dg-final { scan-assembler "\.cfi_offset 143, \-8" } } */
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH v2][GCC] arm: Add support for dwarf debug directives and pseudo hard-register for PAC feature.
2021-12-13 10:44 ` Srinath Parvathaneni
@ 2022-01-12 13:45 ` Srinath Parvathaneni
0 siblings, 0 replies; 5+ messages in thread
From: Srinath Parvathaneni @ 2022-01-12 13:45 UTC (permalink / raw)
To: gcc-patches; +Cc: Kyrylo Tkachov, Richard Earnshaw, Tejas Belagod
Ping!!
________________________________
From: Srinath Parvathaneni <Srinath.Parvathaneni@arm.com>
Sent: 13 December 2021 10:44
To: gcc-patches@gcc.gnu.org <gcc-patches@gcc.gnu.org>
Cc: Kyrylo Tkachov <Kyrylo.Tkachov@arm.com>; Richard Earnshaw <Richard.Earnshaw@arm.com>; Tejas Belagod <Tejas.Belagod@arm.com>
Subject: Re: [PATCH v2][GCC] arm: Add support for dwarf debug directives and pseudo hard-register for PAC feature.
Ping!!
________________________________
From: Srinath Parvathaneni
Sent: 12 November 2021 18:03
To: gcc-patches@gcc.gnu.org <gcc-patches@gcc.gnu.org>
Cc: Kyrylo Tkachov <Kyrylo.Tkachov@arm.com>; Richard Earnshaw <Richard.Earnshaw@arm.com>; Tejas Belagod <Tejas.Belagod@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 "arm-none-eabi-gcc -O2 -mthumb -march=armv8.1-m.main+pacbti -S -fasynchronous-unwind-tables -g"
command line options, the directives supported in this patch looks like below:
...
push {ip}
.save {ra_auth_code}
.cfi_def_cfa_offset 8
.cfi_offset 143, -8
...
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:
2021-11-12 Srinath Parvathaneni <srinath.parvathaneni@arm.com>
* config/arm/aout.h (ra_auth_code): Add to enum.
* config/arm/arm.c (emit_multi_reg_push): Add RA_AUTH_CODE register to
dwarf frame expression instead of IP_REGNUM.
(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:
2021-11-12 Srinath Parvathaneni <srinath.parvathaneni@arm.com>
* g++.target/arm/pac-1.C: New test.
############### Attachment also inlined for ease of reply ###############
diff --git a/gcc/config/arm/aout.h b/gcc/config/arm/aout.h
index 25a2812a663742893b928398b0d3948e97f1905b..c69e299e012f46c8d0711830125dbf2f6b2e93d7 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 8e6ef41f6b065217d1af3f4f1cb85b2d8fbd0dc0..f31944e85c9ab83501f156d138e2aea1bcb5b79d 100644
--- a/gcc/config/arm/arm.h
+++ b/gcc/config/arm/arm.h
@@ -815,7 +815,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]
@@ -856,7 +857,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.
@@ -886,7 +887,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
@@ -1062,10 +1063,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)
@@ -1248,12 +1249,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 ()
@@ -1292,6 +1296,7 @@ enum reg_class
SFP_REG,
AFP_REG,
VPR_REG,
+ PAC_REG,
ALL_REGS,
LIM_REG_CLASSES
};
@@ -1321,6 +1326,7 @@ enum reg_class
"SFP_REG", \
"AFP_REG", \
"VPR_REG", \
+ "PAC_REG", \
"ALL_REGS" \
}
@@ -1349,6 +1355,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. */ \
{ 0xFFFF7FFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0000000F } /* ALL_REGS. */ \
}
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index a3e34747ba52840bd82f76df4a3f05704bd42ec1..966c49a3bf21de909dbab5abcac5d1d3b2af4262 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -22000,7 +22000,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_pac_enabled_for_curr_function_p () && i == IP_REGNUM)
+ reg1 = gen_rtx_REG (SImode, RA_AUTH_CODE);
XVECEXP (par, 0, 0)
= gen_rtx_SET (gen_frame_mem
@@ -22018,7 +22020,7 @@ emit_multi_reg_push (unsigned long mask, unsigned long dwarf_regs_mask)
if (dwarf_regs_mask & (1 << i))
{
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;
}
@@ -23505,7 +23507,10 @@ arm_expand_prologue (void)
saved_regs += arm_save_coproc_regs ();
if (arm_pac_enabled_for_curr_function_p ())
- emit_multi_reg_push (1 << IP_REGNUM, 1 << IP_REGNUM);
+ {
+ insn = emit_multi_reg_push (1 << IP_REGNUM, 1 << IP_REGNUM);
+ RTX_FRAME_RELATED_P (insn) = 1;
+ }
if (frame_pointer_needed && TARGET_ARM)
{
@@ -25435,6 +25440,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)
@@ -29429,6 +29437,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;
}
@@ -29550,6 +29561,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 ();
@@ -29579,6 +29595,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);
@@ -30447,7 +30465,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 564170dc4500c2c5d961c9a19dd86a31416dc965..f27dc3f9041d8b32e7ad750c39143a6764156fe9 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..d33c860f1e368581dd9c3552a7201c7932b8560f
--- /dev/null
+++ b/gcc/testsuite/g++.target/arm/pac-1.C
@@ -0,0 +1,32 @@
+/* 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 "-O2 -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 \{ra_auth_code\}" } } */
+/* { dg-final { scan-assembler "\.cfi_offset 143, \-8" } } */
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2022-07-04 18:33 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-05-05 11:02 [PATCH v2][GCC] arm: Add support for dwarf debug directives and pseudo hard-register for PAC feature Srinath Parvathaneni
2022-07-04 18:33 ` Srinath Parvathaneni
-- strict thread matches above, loose matches on Subject: below --
2021-11-12 18:02 Srinath Parvathaneni
2021-12-13 10:44 ` Srinath Parvathaneni
2022-01-12 13:45 ` Srinath Parvathaneni
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).