public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [PATCH v0 00/13] aarch64: add instructions for Armv9.5-A PAC enhancement
@ 2024-07-08 12:34 Matthieu Longo
  2024-07-08 12:34 ` [PATCH v0 01/13] aarch64: make comment clearer about the location Matthieu Longo
                   ` (12 more replies)
  0 siblings, 13 replies; 14+ messages in thread
From: Matthieu Longo @ 2024-07-08 12:34 UTC (permalink / raw)
  To: binutils; +Cc: Richard Earnshaw, Nick Clifton, Matthieu Longo

Hi,

[patch 0/13] aarch64: add instructions for Armv9.5-A PAC enhancement
    [patch v1 1/13] aarch64: make comment clearer about the location
    [patch v1 2/13] aarch64: constify unchanged char* arguments
    [patch v1 3/13] aarch64: change returned type to bool to match semantic of functions
    [patch v1 4/13] aarch64: improve debuggability on array of enum
    [patch v1 5/13] aarch64: remove redundant register type R_N
    [patch v1 6/13] aarch64: testsuite: remove hard-coded instruction addresses
    [patch v1 7/13] aarch64: add PAuth_LR instructions belonging to NOP space
    [patch v1 8/13] aarch64: add pauth-lr feature option for Armv9.5-A PAC enhancements
    [patch v1 9/13] aarch64: add PAuth_LR instructions with no or one-register operand
    [patch v1 10/13] aarch64: add flag OPD_F_UNSIGNED to distinguish signedness of immediate operands
    [patch v1 11/13] aarch64: add PAuth_LR instructions with imm16 operand
    [patch v1 11/13] aarch64: refactor binary approach for RA signing method to make it extendable
    [patch v1 12/13] aarch64: add DWARF CFI directive for PAuth_LR


The new Armv9.5-A architecture introduces an enhancement of the previous PAuth feature. For context, the Pointer Authentication architecture provides instructions that enable software to sign an address using SP as a diversifier. This form of PAC instruction is typically used for signing return addresses that are stored on the stack. The FEAT_PAuth_LR extension aims to harden the PAC in a signed return address, when signing the return address in LR, the PC is used as a diversifier, in addition to the SP to generate PAC code.


This patch series adds:

- the command-line feature option 'pauth-lr' for Armv9.5-A PAC enhancements. For now, it requires to be explicitly set along the targeted architecture, but will be the default for the future 'armv9.5-a' target architecture.

- the instructions required by Armv9.5-A PAC enhancements.
  * pacm (that belongs to the NOP space, and allows a compatibility mode with the previous PAuth instructions).
  * paci<k>sppc, pacnbi<>sppc, paci<k>171615, auti<k>171615.
  * the imm16 and register variants of the authentication instructions: auti<k>sppc and reta<k>sppc, and auti<k>sppcr and reta<k>sppcr respectively.

- a new register type R_N was also added to prevent a misuse of SP or XZR registers with the register variant instructions.

- a new operand flag OPD_F_UNSIGNED to signal that the immediate value should be treated as an unsigned value. The default signedness of immediate operands is signed.

- a new operand parser (ADDR_UPCREL16) for 16-bits unsigned immediate operand, and a new relocation type (BFD_RELOC_AARCH64_AUTI_LO16_PCREL) specific to the auti<k>sppc and reta<k>sppc instructions and only used for computing the PC-relative offset, but does no relocation.

- a new CFI directive (cfi_negate_ra_state_with_pc) which set an additional bit in the RA state to inform that RA was signed with SP but also PC as an additional diversifier. (more details at https://github.com/ARM-software/abi-aa/pull/245)
RA state | Description
-------------------------------------------------------------------------
0b00     | Return address not signed (default if no cfi_negate_ra_state*)
0b01     | Return address signed with SP (cfi_negate_ra_state)
0b10     | Invalid state
0b11     | Return address signed with SP+PC (cfi_negate_ra_state_with_pc)


Each patch also adds relevant tests.
Regression tested on aarch64-unknown-linux-gnu, and no regression found.

Ok for binutils-master?

Regards,
Matthieu.

Matthieu Longo (13):
  aarch64: make comment clearer about the location
  aarch64: constify unchanged char* arguments
  aarch64: change returned type to bool to match semantic of functions
  aarch64: improve debuggability on array of enum
  aarch64: remove redundant register type R_N
  aarch64: testsuite: remove hard-coded instruction addresses
  aarch64: refactor binary approach for RA signing method to make it extendable
  aarch64: add PAuth_LR instructions belonging to NOP space
  aarch64: add pauth-lr feature option for Armv9.5-A PAC enhancements
  aarch64: add PAuth_LR instructions with no or one-register operand
  aarch64: add flag OPD_F_UNSIGNED to distinguish signedness of immediate operands
  aarch64: add PAuth_LR instructions with imm16 operand
  aarch64: add DWARF CFI directive for PAuth_LR

 bfd/elf-eh-frame.c                            |   1 +
 bfd/elfnn-aarch64.c                           |   8 +-
 bfd/reloc.c                                   |  17 +-
 binutils/dwarf.c                              |   5 +
 gas/config/tc-aarch64.c                       |  68 ++-
 gas/dw2gencfi.c                               |  10 +
 gas/gen-sframe.c                              |  46 +-
 gas/gen-sframe.h                              |  15 +-
 gas/scfidw2gen.c                              |   1 +
 .../gas/aarch64/pac_negate_ra_state_with_pc.d |  64 +++
 .../gas/aarch64/pac_negate_ra_state_with_pc.s |  53 ++
 gas/testsuite/gas/aarch64/pauth_lr-bad.d      |   3 +
 gas/testsuite/gas/aarch64/pauth_lr-bad.l      |  19 +
 gas/testsuite/gas/aarch64/pauth_lr-bad.s      |  27 +
 gas/testsuite/gas/aarch64/pauth_lr.d          |  37 ++
 gas/testsuite/gas/aarch64/pauth_lr.s          |  47 ++
 gas/testsuite/gas/aarch64/system-3.d          |  54 +-
 gas/testsuite/gas/aarch64/system-3.s          |   4 +
 gas/testsuite/gas/aarch64/system.d            |   2 +-
 include/dwarf2.def                            |   4 +-
 include/opcode/aarch64.h                      |  16 +-
 include/sframe.h                              |   4 +-
 opcodes/aarch64-opc.c                         | 462 ++++++++++--------
 opcodes/aarch64-opc.h                         |   9 +-
 opcodes/aarch64-tbl.h                         |  36 ++
 25 files changed, 748 insertions(+), 264 deletions(-)
 create mode 100644 gas/testsuite/gas/aarch64/pac_negate_ra_state_with_pc.d
 create mode 100644 gas/testsuite/gas/aarch64/pac_negate_ra_state_with_pc.s
 create mode 100644 gas/testsuite/gas/aarch64/pauth_lr-bad.d
 create mode 100644 gas/testsuite/gas/aarch64/pauth_lr-bad.l
 create mode 100644 gas/testsuite/gas/aarch64/pauth_lr-bad.s
 create mode 100644 gas/testsuite/gas/aarch64/pauth_lr.d
 create mode 100644 gas/testsuite/gas/aarch64/pauth_lr.s

-- 
2.45.1


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH v0 01/13] aarch64: make comment clearer about the location
  2024-07-08 12:34 [PATCH v0 00/13] aarch64: add instructions for Armv9.5-A PAC enhancement Matthieu Longo
@ 2024-07-08 12:34 ` Matthieu Longo
  2024-07-08 12:34 ` [PATCH v0 02/13] aarch64: constify unchanged char* arguments Matthieu Longo
                   ` (11 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: Matthieu Longo @ 2024-07-08 12:34 UTC (permalink / raw)
  To: binutils; +Cc: Richard Earnshaw, Nick Clifton, Matthieu Longo

[-- Attachment #1: Type: text/plain, Size: 439 bytes --]


The enum aarch64_opnd_qualifiers in include/opcode/aarch64.h needs to
stay in sync with the array of struct operand_qualifier_data which
defines various properties for the different type of operands. For
instance, for:
- registers: the size of the register, the number of elements.
- immediates: lower and upper bits to determine the range of values.
---
 include/opcode/aarch64.h | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: v0-0001-aarch64-make-comment-clearer-about-the-location.patch --]
[-- Type: text/x-patch; name="v0-0001-aarch64-make-comment-clearer-about-the-location.patch", Size: 545 bytes --]

diff --git a/include/opcode/aarch64.h b/include/opcode/aarch64.h
index dfed0a509b2..756d4295ccd 100644
--- a/include/opcode/aarch64.h
+++ b/include/opcode/aarch64.h
@@ -890,7 +890,8 @@ enum aarch64_opnd
 /* Qualifier constrains an operand.  It either specifies a variant of an
    operand type or limits values available to an operand type.
 
-   N.B. Order is important; keep aarch64_opnd_qualifiers synced.  */
+   N.B. Order is important.
+   Keep aarch64_opnd_qualifiers (opcodes/aarch64-opc.c) synced.  */
 
 enum aarch64_opnd_qualifier
 {

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH v0 02/13] aarch64: constify unchanged char* arguments
  2024-07-08 12:34 [PATCH v0 00/13] aarch64: add instructions for Armv9.5-A PAC enhancement Matthieu Longo
  2024-07-08 12:34 ` [PATCH v0 01/13] aarch64: make comment clearer about the location Matthieu Longo
@ 2024-07-08 12:34 ` Matthieu Longo
  2024-07-08 12:34 ` [PATCH v0 03/13] aarch64: change returned type to bool to match semantic of functions Matthieu Longo
                   ` (10 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: Matthieu Longo @ 2024-07-08 12:34 UTC (permalink / raw)
  To: binutils; +Cc: Richard Earnshaw, Nick Clifton, Matthieu Longo

[-- Attachment #1: Type: text/plain, Size: 84 bytes --]

---
 gas/config/tc-aarch64.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: v0-0002-aarch64-constify-unchanged-char-arguments.patch --]
[-- Type: text/x-patch; name="v0-0002-aarch64-constify-unchanged-char-arguments.patch", Size: 482 bytes --]

diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c
index 3dfbeb7bd00..7ee29cc8562 100644
--- a/gas/config/tc-aarch64.c
+++ b/gas/config/tc-aarch64.c
@@ -6236,7 +6236,7 @@ lookup_mnemonic (const char *start, int len)
    (if any) and END points to the end of the mnemonic.  */
 
 static templates *
-opcode_lookup (char *base, char *dot, char *end)
+opcode_lookup (const char *base, const char *dot, const char *end)
 {
   const aarch64_cond *cond;
   char condname[16];

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH v0 03/13] aarch64: change returned type to bool to match semantic of functions
  2024-07-08 12:34 [PATCH v0 00/13] aarch64: add instructions for Armv9.5-A PAC enhancement Matthieu Longo
  2024-07-08 12:34 ` [PATCH v0 01/13] aarch64: make comment clearer about the location Matthieu Longo
  2024-07-08 12:34 ` [PATCH v0 02/13] aarch64: constify unchanged char* arguments Matthieu Longo
@ 2024-07-08 12:34 ` Matthieu Longo
  2024-07-08 12:34 ` [PATCH v0 04/13] aarch64: improve debuggability on array of enum Matthieu Longo
                   ` (9 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: Matthieu Longo @ 2024-07-08 12:34 UTC (permalink / raw)
  To: binutils; +Cc: Richard Earnshaw, Nick Clifton, Matthieu Longo

[-- Attachment #1: Type: text/plain, Size: 201 bytes --]

---
 include/opcode/aarch64.h |   3 +-
 opcodes/aarch64-opc.c    | 340 +++++++++++++++++++--------------------
 opcodes/aarch64-opc.h    |   2 +-
 3 files changed, 173 insertions(+), 172 deletions(-)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: v0-0003-aarch64-change-returned-type-to-bool-to-match-sem.patch --]
[-- Type: text/x-patch; name="v0-0003-aarch64-change-returned-type-to-bool-to-match-sem.patch", Size: 42907 bytes --]

diff --git a/include/opcode/aarch64.h b/include/opcode/aarch64.h
index 756d4295ccd..61e31cc53f6 100644
--- a/include/opcode/aarch64.h
+++ b/include/opcode/aarch64.h
@@ -23,6 +23,7 @@
 #define OPCODE_AARCH64_H
 
 #include "bfd.h"
+#include <stdbool.h>
 #include <stdint.h>
 #include <assert.h>
 #include <stdlib.h>
@@ -1921,7 +1922,7 @@ aarch64_is_destructive_by_operands (const aarch64_opcode *);
 extern int
 aarch64_num_of_operands (const aarch64_opcode *);
 
-extern int
+extern bool
 aarch64_stack_pointer_p (const aarch64_opnd_info *);
 
 extern int
diff --git a/opcodes/aarch64-opc.c b/opcodes/aarch64-opc.c
index 0b090557808..437e125c46d 100644
--- a/opcodes/aarch64-opc.c
+++ b/opcodes/aarch64-opc.c
@@ -638,21 +638,21 @@ const struct aarch64_name_value_pair aarch64_prfops[32] =
 \f
 /* Utilities on value constraint.  */
 
-static inline int
-value_in_range_p (int64_t value, int low, int high)
+static inline bool
+value_in_range_p (int64_t value, int64_t low, int64_t high)
 {
-  return (value >= low && value <= high) ? 1 : 0;
+  return (low <= value) && (value <= high);
 }
 
 /* Return true if VALUE is a multiple of ALIGN.  */
-static inline int
+static inline bool
 value_aligned_p (int64_t value, int align)
 {
   return (value % align) == 0;
 }
 
 /* A signed value fits in a field.  */
-static inline int
+static inline bool
 value_fit_signed_field_p (int64_t value, unsigned width)
 {
   assert (width < 32);
@@ -660,13 +660,13 @@ value_fit_signed_field_p (int64_t value, unsigned width)
     {
       int64_t lim = (uint64_t) 1 << (width - 1);
       if (value >= -lim && value < lim)
-	return 1;
+	return true;
     }
-  return 0;
+  return false;
 }
 
 /* An unsigned value fits in a field.  */
-static inline int
+static inline bool
 value_fit_unsigned_field_p (int64_t value, unsigned width)
 {
   assert (width < 32);
@@ -674,13 +674,13 @@ value_fit_unsigned_field_p (int64_t value, unsigned width)
     {
       int64_t lim = (uint64_t) 1 << width;
       if (value >= 0 && value < lim)
-	return 1;
+	return true;
     }
-  return 0;
+  return false;
 }
 
-/* Return 1 if OPERAND is SP or WSP.  */
-int
+/* Return true if OPERAND is SP or WSP.  */
+bool
 aarch64_stack_pointer_p (const aarch64_opnd_info *operand)
 {
   return ((aarch64_get_operand_class (operand->type)
@@ -703,7 +703,7 @@ aarch64_zero_register_p (const aarch64_opnd_info *operand)
    OPERAND->TYPE and been qualified by OPERAND->QUALIFIER can be also
    qualified by the qualifier TARGET.  */
 
-static inline int
+static inline bool
 operand_also_qualified_p (const struct aarch64_opnd_info *operand,
 			  aarch64_opnd_qualifier_t target)
 {
@@ -711,27 +711,27 @@ operand_also_qualified_p (const struct aarch64_opnd_info *operand,
     {
     case AARCH64_OPND_QLF_W:
       if (target == AARCH64_OPND_QLF_WSP && aarch64_stack_pointer_p (operand))
-	return 1;
+	return true;
       break;
     case AARCH64_OPND_QLF_X:
       if (target == AARCH64_OPND_QLF_SP && aarch64_stack_pointer_p (operand))
-	return 1;
+	return true;
       break;
     case AARCH64_OPND_QLF_WSP:
       if (target == AARCH64_OPND_QLF_W
 	  && operand_maybe_stack_pointer (aarch64_operands + operand->type))
-	return 1;
+	return true;
       break;
     case AARCH64_OPND_QLF_SP:
       if (target == AARCH64_OPND_QLF_X
 	  && operand_maybe_stack_pointer (aarch64_operands + operand->type))
-	return 1;
+	return true;
       break;
     default:
       break;
     }
 
-  return 0;
+  return false;
 }
 
 /* Given qualifier sequence list QSEQ_LIST and the known qualifier KNOWN_QLF
@@ -1729,7 +1729,7 @@ calc_ldst_datasize (const aarch64_opnd_info *opnds)
    use a combination of error code, static string and some integer data to
    represent an error.  */
 
-static int
+static bool
 operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 				  enum aarch64_opnd type,
 				  const aarch64_opcode *opcode,
@@ -1757,7 +1757,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 	      set_syntax_error (mismatch_detail, idx - 1,
 				_("second reg in pair should be xzr if first is"
 				  " xzr"));
-	      return 0;
+	      return false;
 	    }
 	}
       /* Check pair reg constraints for instructions taking a pair of
@@ -1770,13 +1770,13 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 	    {
 	      set_syntax_error (mismatch_detail, idx - 1,
 				_("reg pair must start from even reg"));
-	      return 0;
+	      return false;
 	    }
 	  if (opnds[idx].reg.regno != opnds[idx - 1].reg.regno + 1)
 	    {
 	      set_syntax_error (mismatch_detail, idx,
 				_("reg pair must be contiguous"));
-	      return 0;
+	      return false;
 	    }
 	  break;
 	}
@@ -1790,13 +1790,13 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 	      && !aarch64_sys_ins_reg_has_xt (opnds[0].sysins_op))
 	    {
 	      set_other_error (mismatch_detail, idx, _("extraneous register"));
-	      return 0;
+	      return false;
 	    }
 	  if (!opnds[1].present
 	      && aarch64_sys_ins_reg_has_xt (opnds[0].sysins_op))
 	    {
 	      set_other_error (mismatch_detail, idx, _("missing register"));
-	      return 0;
+	      return false;
 	    }
 	}
       switch (qualifier)
@@ -1807,7 +1807,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 	    {
 	      set_other_error (mismatch_detail, idx,
 		       _("stack pointer register expected"));
-	      return 0;
+	      return false;
 	    }
 	  break;
 	default:
@@ -1830,7 +1830,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 	  if (!check_reglane (opnd, mismatch_detail, idx,
 			      "z", 0, (1 << shift) - 1,
 			      0, (1u << (size - shift)) - 1))
-	    return 0;
+	    return false;
 	  break;
 
 	case AARCH64_OPND_SVE_Zm1_23_INDEX:
@@ -1849,14 +1849,14 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 	  size = aarch64_get_qualifier_esize (opnd->qualifier);
 	  if (!check_reglane (opnd, mismatch_detail, idx, "z", 0, 31,
 			      0, 64 / size - 1))
-	    return 0;
+	    return false;
 	  break;
 
 	case AARCH64_OPND_SVE_Zn_5_INDEX:
 	  size = aarch64_get_qualifier_esize (opnd->qualifier);
 	  if (!check_reglane (opnd, mismatch_detail, idx, "z", 0, 31,
 			      0, 16 / size - 1))
-	    return 0;
+	    return false;
 	  break;
 
 	case AARCH64_OPND_SME_PNn3_INDEX1:
@@ -1864,7 +1864,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 	  size = get_operand_field_width (get_operand_from_code (type), 1);
 	  if (!check_reglane (opnd, mismatch_detail, idx, "pn", 8, 15,
 			      0, (1 << size) - 1))
-	    return 0;
+	    return false;
 	  break;
 
 	case AARCH64_OPND_SVE_Zm3_12_INDEX:
@@ -1877,7 +1877,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 	  size = get_operand_fields_width (get_operand_from_code (type)) - 5;
 	  if (!check_reglane (opnd, mismatch_detail, idx, "z", 0, 31,
 			      0, (1 << size) - 1))
-	    return 0;
+	    return false;
 	  break;
 
 	case AARCH64_OPND_SME_Zm_INDEX1:
@@ -1894,14 +1894,14 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 	  size = get_operand_fields_width (get_operand_from_code (type)) - 4;
 	  if (!check_reglane (opnd, mismatch_detail, idx, "z", 0, 15,
 			      0, (1 << size) - 1))
-	    return 0;
+	    return false;
 	  break;
 
 	case AARCH64_OPND_SME_Zm:
 	  if (opnd->reg.regno > 15)
 	    {
 	      set_invalid_regno_error (mismatch_detail, idx, "z", 0, 15);
-	      return 0;
+	      return false;
 	    }
 	  break;
 
@@ -1910,7 +1910,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 	  max_value = 16 / size - 1;
 	  if (!check_za_access (opnd, mismatch_detail, idx,
 				12, max_value, 1, 0))
-	    return 0;
+	    return false;
 	  break;
 
 	default:
@@ -1931,12 +1931,12 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 	case AARCH64_OPND_SME_Znx4:
 	  num = get_operand_specific_data (&aarch64_operands[type]);
 	  if (!check_reglist (opnd, mismatch_detail, idx, num, 1))
-	    return 0;
+	    return false;
 	  if ((opnd->reglist.first_regno % num) != 0)
 	    {
 	      set_other_error (mismatch_detail, idx,
 			       _("start register out of range"));
-	      return 0;
+	      return false;
 	    }
 	  break;
 
@@ -1947,13 +1947,13 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 	     have a stride of 4.  */
 	  num = get_operand_specific_data (&aarch64_operands[type]);
 	  if (!check_reglist (opnd, mismatch_detail, idx, num, 16 / num))
-	    return 0;
+	    return false;
 	  num = 16 | (opnd->reglist.stride - 1);
 	  if ((opnd->reglist.first_regno & ~num) != 0)
 	    {
 	      set_other_error (mismatch_detail, idx,
 			       _("start register out of range"));
-	      return 0;
+	      return false;
 	    }
 	  break;
 
@@ -1962,7 +1962,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 	case AARCH64_OPND_SVE_ZtxN:
 	  num = get_opcode_dependent_value (opcode);
 	  if (!check_reglist (opnd, mismatch_detail, idx, num, 1))
-	    return 0;
+	    return false;
 	  break;
 
 	default:
@@ -1980,87 +1980,87 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 	  max_value = 16 / size - 1;
 	  if (!check_za_access (opnd, mismatch_detail, idx, 12, max_value, 1,
 				get_opcode_dependent_value (opcode)))
-	    return 0;
+	    return false;
 	  break;
 
 	case AARCH64_OPND_SME_ZA_array_off4:
 	  if (!check_za_access (opnd, mismatch_detail, idx, 12, 15, 1,
 				get_opcode_dependent_value (opcode)))
-	    return 0;
+	    return false;
 	  break;
 
 	case AARCH64_OPND_SME_ZA_array_off3_0:
 	case AARCH64_OPND_SME_ZA_array_off3_5:
 	  if (!check_za_access (opnd, mismatch_detail, idx, 8, 7, 1,
 				get_opcode_dependent_value (opcode)))
-	    return 0;
+	    return false;
 	  break;
 
 	case AARCH64_OPND_SME_ZA_array_off1x4:
 	  if (!check_za_access (opnd, mismatch_detail, idx, 8, 1, 4,
 				get_opcode_dependent_value (opcode)))
-	    return 0;
+	    return false;
 	  break;
 
 	case AARCH64_OPND_SME_ZA_array_off2x2:
 	  if (!check_za_access (opnd, mismatch_detail, idx, 8, 3, 2,
 				get_opcode_dependent_value (opcode)))
-	    return 0;
+	    return false;
 	  break;
 
 	case AARCH64_OPND_SME_ZA_array_off2x4:
 	  if (!check_za_access (opnd, mismatch_detail, idx, 8, 3, 4,
 				get_opcode_dependent_value (opcode)))
-	    return 0;
+	    return false;
 	  break;
 
 	case AARCH64_OPND_SME_ZA_array_off3x2:
 	  if (!check_za_access (opnd, mismatch_detail, idx, 8, 7, 2,
 				get_opcode_dependent_value (opcode)))
-	    return 0;
+	    return false;
 	  break;
 
 	case AARCH64_OPND_SME_ZA_array_vrsb_1:
 	  if (!check_za_access (opnd, mismatch_detail, idx, 12, 7, 2,
 				get_opcode_dependent_value (opcode)))
-	    return 0;
+	    return false;
 	  break;
 
 	case AARCH64_OPND_SME_ZA_array_vrsh_1:
 	  if (!check_za_access (opnd, mismatch_detail, idx, 12, 3, 2,
 				get_opcode_dependent_value (opcode)))
-	    return 0;
+	    return false;
 	  break;
 
 	case AARCH64_OPND_SME_ZA_array_vrss_1:
 	  if (!check_za_access (opnd, mismatch_detail, idx, 12, 1, 2,
 				get_opcode_dependent_value (opcode)))
-	    return 0;
+	    return false;
 	  break;
 
 	case AARCH64_OPND_SME_ZA_array_vrsd_1:
 	  if (!check_za_access (opnd, mismatch_detail, idx, 12, 0, 2,
 				get_opcode_dependent_value (opcode)))
-	    return 0;
+	    return false;
 	  break;
 
 	case AARCH64_OPND_SME_ZA_array_vrsb_2:
 	  if (!check_za_access (opnd, mismatch_detail, idx, 12, 3, 4,
 				get_opcode_dependent_value (opcode)))
-	    return 0;
+	    return false;
 	  break;
 
 	case AARCH64_OPND_SME_ZA_array_vrsh_2:
 	  if (!check_za_access (opnd, mismatch_detail, idx, 12, 1, 4,
 				get_opcode_dependent_value (opcode)))
-	    return 0;
+	    return false;
 	  break;
 
 	case AARCH64_OPND_SME_ZA_array_vrss_2:
 	case AARCH64_OPND_SME_ZA_array_vrsd_2:
 	  if (!check_za_access (opnd, mismatch_detail, idx, 12, 0, 4,
 				get_opcode_dependent_value (opcode)))
-	    return 0;
+	    return false;
 	  break;
 
 	case AARCH64_OPND_SME_ZA_HV_idx_srcxN:
@@ -2072,7 +2072,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 	    max_value -= 1;
 	  if (!check_za_access (opnd, mismatch_detail, idx,
 				12, max_value, num, 0))
-	    return 0;
+	    return false;
 	  break;
 
 	default:
@@ -2088,7 +2088,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 	  if (opnd->reg.regno < 8)
 	    {
 	      set_invalid_regno_error (mismatch_detail, idx, "pn", 8, 15);
-	      return 0;
+	      return false;
 	    }
 	  break;
 
@@ -2097,7 +2097,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 	      && get_operand_fields_width (get_operand_from_code (type)) == 3)
 	    {
 	      set_invalid_regno_error (mismatch_detail, idx, "p", 0, 7);
-	      return 0;
+	      return false;
 	    }
 	  break;
 	}
@@ -2125,7 +2125,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 	    {
 	      set_syntax_error (mismatch_detail, idx,
 				_("unexpected address writeback"));
-	      return 0;
+	      return false;
 	    }
 	  break;
 	case ldst_imm10:
@@ -2133,7 +2133,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 	    {
 	      set_syntax_error (mismatch_detail, idx,
 				_("unexpected address writeback"));
-	      return 0;
+	      return false;
 	    }
 	  break;
 	case ldst_imm9:
@@ -2144,7 +2144,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 	    {
 	      set_syntax_error (mismatch_detail, idx,
 				_("address writeback expected"));
-	      return 0;
+	      return false;
 	    }
 	  break;
 	case rcpc3:
@@ -2156,7 +2156,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 	      {
 		set_syntax_error (mismatch_detail, idx,
 				  _("unexpected address writeback"));
-		return 0;
+		return false;
 	      }
 
 	  break;
@@ -2176,12 +2176,12 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 	    {
 	      set_offset_out_of_range_error (mismatch_detail, idx,
 					     -64 * size, 63 * size);
-	      return 0;
+	      return false;
 	    }
 	  if (!value_aligned_p (opnd->addr.offset.imm, size))
 	    {
 	      set_unaligned_error (mismatch_detail, idx, size);
-	      return 0;
+	      return false;
 	    }
 	  break;
 	case AARCH64_OPND_ADDR_OFFSET:
@@ -2190,7 +2190,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 	  if (!value_in_range_p (opnd->addr.offset.imm, -256, 255))
 	    {
 	      set_offset_out_of_range_error (mismatch_detail, idx, -256, 255);
-	      return 0;
+	      return false;
 	    }
 	  break;
 
@@ -2201,22 +2201,22 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 	  if ((value_in_range_p (opnd->addr.offset.imm, 0, 255)
 	       && !value_aligned_p (opnd->addr.offset.imm, size))
 	      || value_in_range_p (opnd->addr.offset.imm, -256, -1))
-	    return 1;
+	    return true;
 	  set_other_error (mismatch_detail, idx,
 			   _("negative or unaligned offset expected"));
-	  return 0;
+	  return false;
 
 	case AARCH64_OPND_ADDR_SIMM10:
 	  /* Scaled signed 10 bits immediate offset.  */
 	  if (!value_in_range_p (opnd->addr.offset.imm, -4096, 4088))
 	    {
 	      set_offset_out_of_range_error (mismatch_detail, idx, -4096, 4088);
-	      return 0;
+	      return false;
 	    }
 	  if (!value_aligned_p (opnd->addr.offset.imm, 8))
 	    {
 	      set_unaligned_error (mismatch_detail, idx, 8);
-	      return 0;
+	      return false;
 	    }
 	  break;
 
@@ -2225,13 +2225,13 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 	  if (!value_in_range_p (opnd->addr.offset.imm, -1024, 1008))
 	    {
 	      set_offset_out_of_range_error (mismatch_detail, idx, -1024, 1008);
-	      return 0;
+	      return false;
 	    }
 
 	  if (!value_aligned_p (opnd->addr.offset.imm, 16))
 	    {
 	      set_unaligned_error (mismatch_detail, idx, 16);
-	      return 0;
+	      return false;
 	    }
 	  break;
 
@@ -2240,13 +2240,13 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 	  if (!value_in_range_p (opnd->addr.offset.imm, -4096, 4080))
 	    {
 	      set_offset_out_of_range_error (mismatch_detail, idx, -4096, 4080);
-	      return 0;
+	      return false;
 	    }
 
 	  if (!value_aligned_p (opnd->addr.offset.imm, 16))
 	    {
 	      set_unaligned_error (mismatch_detail, idx, 16);
-	      return 0;
+	      return false;
 	    }
 	  break;
 
@@ -2256,12 +2256,12 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 	  if (opnd->addr.offset.is_reg)
 	    {
 	      if (value_in_range_p (opnd->addr.offset.regno, 0, 30))
-		return 1;
+		return true;
 	      else
 		{
 		  set_other_error (mismatch_detail, idx,
 				   _("invalid register offset"));
-		  return 0;
+		  return false;
 		}
 	    }
 	  else
@@ -2283,7 +2283,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 		{
 		  set_other_error (mismatch_detail, idx,
 				   _("invalid post-increment amount"));
-		  return 0;
+		  return false;
 		}
 	    }
 	  break;
@@ -2299,7 +2299,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 	    {
 	      set_other_error (mismatch_detail, idx,
 			       _("invalid shift amount"));
-	      return 0;
+	      return false;
 	    }
 	  /* Only UXTW, LSL, SXTW and SXTX are the accepted extending
 	     operators.  */
@@ -2312,7 +2312,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 	    default:
 	      set_other_error (mismatch_detail, idx,
 			       _("invalid extend/shift operator"));
-	      return 0;
+	      return false;
 	    }
 	  break;
 
@@ -2326,12 +2326,12 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 	    {
 	      set_offset_out_of_range_error (mismatch_detail, idx,
 					     0, 4095 * size);
-	      return 0;
+	      return false;
 	    }
 	  if (!value_aligned_p (opnd->addr.offset.imm, size))
 	    {
 	      set_unaligned_error (mismatch_detail, idx, size);
-	      return 0;
+	      return false;
 	    }
 	  break;
 
@@ -2347,7 +2347,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 	      if (!value_aligned_p (imm, 4))
 		{
 		  set_unaligned_error (mismatch_detail, idx, 4);
-		  return 0;
+		  return false;
 		}
 	      /* Right shift by 2 so that we can carry out the following check
 		 canonically.  */
@@ -2358,7 +2358,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 	    {
 	      set_other_error (mismatch_detail, idx,
 			       _("immediate out of range"));
-	      return 0;
+	      return false;
 	    }
 	  break;
 
@@ -2366,7 +2366,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 	  if (!value_in_range_p (opnd->addr.offset.imm, 0, 15))
 	    {
 	      set_offset_out_of_range_error (mismatch_detail, idx, 0, 15);
-	      return 0;
+	      return false;
 	    }
 	  break;
 
@@ -2388,18 +2388,18 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 	    {
 	      set_other_error (mismatch_detail, idx,
 			       _("invalid addressing mode"));
-	      return 0;
+	      return false;
 	    }
 	  if (!value_in_range_p (opnd->addr.offset.imm, min_value, max_value))
 	    {
 	      set_offset_out_of_range_error (mismatch_detail, idx,
 					     min_value, max_value);
-	      return 0;
+	      return false;
 	    }
 	  if (!value_aligned_p (opnd->addr.offset.imm, num))
 	    {
 	      set_unaligned_error (mismatch_detail, idx, num);
-	      return 0;
+	      return false;
 	    }
 	  break;
 
@@ -2430,18 +2430,18 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 	    {
 	      set_other_error (mismatch_detail, idx,
 			       _("invalid addressing mode"));
-	      return 0;
+	      return false;
 	    }
 	  if (!value_in_range_p (opnd->addr.offset.imm, min_value, max_value))
 	    {
 	      set_offset_out_of_range_error (mismatch_detail, idx,
 					     min_value, max_value);
-	      return 0;
+	      return false;
 	    }
 	  if (!value_aligned_p (opnd->addr.offset.imm, num))
 	    {
 	      set_unaligned_error (mismatch_detail, idx, num);
-	      return 0;
+	      return false;
 	    }
 	  break;
 
@@ -2486,7 +2486,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 	    {
 	      set_other_error (mismatch_detail, idx,
 			       _("index register xzr is not allowed"));
-	      return 0;
+	      return false;
 	    }
 	  if (((1 << opnd->shifter.kind) & modifiers) == 0
 	      || (opnd->shifter.amount
@@ -2494,7 +2494,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 	    {
 	      set_other_error (mismatch_detail, idx,
 			       _("invalid addressing mode"));
-	      return 0;
+	      return false;
 	    }
 	  break;
 
@@ -2528,7 +2528,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 	    {
 	      set_other_error (mismatch_detail, idx,
 			       _("invalid addressing mode"));
-	      return 0;
+	      return false;
 	    }
 	  break;
 
@@ -2555,7 +2555,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 	      {
 		set_other_error (mismatch_detail, idx,
 				 _("invalid increment amount"));
-		return 0;
+		return false;
 	      }
 	  }
 	  break;
@@ -2564,7 +2564,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 	  if (!value_in_range_p (opnd->addr.offset.imm, -256, 255))
 	    {
 	      set_imm_out_of_range_error (mismatch_detail, idx, -256, 255);
-	      return 0;
+	      return false;
 	    }
 
 	default:
@@ -2580,7 +2580,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 	  if (!value_in_range_p (opnd->reglist.index, 0, num))
 	    {
 	      set_elem_idx_out_of_range_error (mismatch_detail, idx, 0, num);
-	      return 0;
+	      return false;
 	    }
 	}
       /* The opcode dependent area stores the number of elements in
@@ -2597,7 +2597,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 	  /* Unless LD1/ST1, the number of registers should be equal to that
 	     of the structure elements.  */
 	  if (num != 1 && !check_reglist (opnd, mismatch_detail, idx, num, 1))
-	    return 0;
+	    return false;
 	  break;
 	case AARCH64_OPND_LVt_AL:
 	case AARCH64_OPND_LEt:
@@ -2605,7 +2605,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 	  /* The number of registers should be equal to that of the structure
 	     elements.  */
 	  if (!check_reglist (opnd, mismatch_detail, idx, num, 1))
-	    return 0;
+	    return false;
 	  break;
 	default:
 	  break;
@@ -2613,7 +2613,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
       if (opnd->reglist.stride != 1)
 	{
 	  set_reg_list_stride_error (mismatch_detail, idx, 1);
-	  return 0;
+	  return false;
 	}
       break;
 
@@ -2628,7 +2628,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 	  set_imm_out_of_range_error (mismatch_detail, idx,
 				      get_lower_bound (qualifier),
 				      get_upper_bound (qualifier));
-	  return 0;
+	  return false;
 	}
 
       switch (type)
@@ -2638,19 +2638,19 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 	    {
 	      set_other_error (mismatch_detail, idx,
 			       _("invalid shift operator"));
-	      return 0;
+	      return false;
 	    }
 	  if (opnd->shifter.amount != 0 && opnd->shifter.amount != 12)
 	    {
 	      set_other_error (mismatch_detail, idx,
 			       _("shift amount must be 0 or 12"));
-	      return 0;
+	      return false;
 	    }
 	  if (!value_fit_unsigned_field_p (opnd->imm.value, 12))
 	    {
 	      set_other_error (mismatch_detail, idx,
 			       _("immediate out of range"));
-	      return 0;
+	      return false;
 	    }
 	  break;
 
@@ -2660,32 +2660,32 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 	    {
 	      set_other_error (mismatch_detail, idx,
 			       _("invalid shift operator"));
-	      return 0;
+	      return false;
 	    }
 	  size = aarch64_get_qualifier_esize (opnds[0].qualifier);
 	  if (!value_aligned_p (opnd->shifter.amount, 16))
 	    {
 	      set_other_error (mismatch_detail, idx,
 			       _("shift amount must be a multiple of 16"));
-	      return 0;
+	      return false;
 	    }
 	  if (!value_in_range_p (opnd->shifter.amount, 0, size * 8 - 16))
 	    {
 	      set_sft_amount_out_of_range_error (mismatch_detail, idx,
 						 0, size * 8 - 16);
-	      return 0;
+	      return false;
 	    }
 	  if (opnd->imm.value < 0)
 	    {
 	      set_other_error (mismatch_detail, idx,
 			       _("negative immediate value not allowed"));
-	      return 0;
+	      return false;
 	    }
 	  if (!value_fit_unsigned_field_p (opnd->imm.value, 16))
 	    {
 	      set_other_error (mismatch_detail, idx,
 			       _("immediate out of range"));
-	      return 0;
+	      return false;
 	    }
 	  break;
 
@@ -2704,7 +2704,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 		    {
 		      set_other_error (mismatch_detail, idx,
 				       _("immediate out of range"));
-		      return 0;
+		      return false;
 		    }
 		  break;
 		case OP_MOV_IMM_LOG:
@@ -2712,12 +2712,12 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 		    {
 		      set_other_error (mismatch_detail, idx,
 				       _("immediate out of range"));
-		      return 0;
+		      return false;
 		    }
 		  break;
 		default:
 		  assert (0);
-		  return 0;
+		  return false;
 		}
 	    }
 	  break;
@@ -2744,7 +2744,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 	    {
 	      set_imm_out_of_range_error (mismatch_detail, idx, 0,
 					  (1u << size) - 1);
-	      return 0;
+	      return false;
 	    }
 	  break;
 
@@ -2753,13 +2753,13 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 	  if (!value_in_range_p (opnd->imm.value, 0, 1008))
 	    {
 	      set_imm_out_of_range_error (mismatch_detail, idx, 0, 1008);
-	      return 0;
+	      return false;
 	    }
 
 	  if (!value_aligned_p (opnd->imm.value, 16))
 	    {
 	      set_unaligned_error (mismatch_detail, idx, 16);
-	      return 0;
+	      return false;
 	    }
 	  break;
 
@@ -2776,7 +2776,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 	      set_imm_out_of_range_error (mismatch_detail, idx,
 					  -(1 << (size - 1)),
 					  (1 << (size - 1)) - 1);
-	      return 0;
+	      return false;
 	    }
 	  break;
 
@@ -2789,7 +2789,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 	    {
 	      set_imm_out_of_range_error (mismatch_detail, idx, 1,
 					  size - opnds[idx-1].imm.value);
-	      return 0;
+	      return false;
 	    }
 	  break;
 
@@ -2804,7 +2804,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 	      {
 		set_other_error (mismatch_detail, idx,
 				 _("immediate out of range"));
-		return 0;
+		return false;
 	      }
 	  }
 	  break;
@@ -2815,7 +2815,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 	    {
 	      set_other_error (mismatch_detail, idx,
 			       _("immediate zero expected"));
-	      return 0;
+	      return false;
 	    }
 	  break;
 
@@ -2829,7 +2829,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 	    {
 	      set_other_error (mismatch_detail, idx,
 			       _("rotate expected to be 0, 90, 180 or 270"));
-	      return 0;
+	      return false;
 	    }
 	  break;
 
@@ -2840,7 +2840,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 	    {
 	      set_other_error (mismatch_detail, idx,
 			       _("rotate expected to be 90 or 270"));
-	      return 0;
+	      return false;
 	    }
 	  break;
 
@@ -2851,7 +2851,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 	    {
 	      set_other_error (mismatch_detail, idx,
 			       _("invalid shift amount"));
-	      return 0;
+	      return false;
 	    }
 	  break;
 
@@ -2861,7 +2861,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 	    {
 	      set_imm_out_of_range_error (mismatch_detail, idx, 0,
 					  size * 8 - 1);
-	      return 0;
+	      return false;
 	    }
 	  break;
 
@@ -2870,7 +2870,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 	  if (!value_in_range_p (opnd->imm.value, 1, size * 8))
 	    {
 	      set_imm_out_of_range_error (mismatch_detail, idx, 1, size * 8);
-	      return 0;
+	      return false;
 	    }
 	  break;
 
@@ -2884,7 +2884,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 		{
 		  set_other_error (mismatch_detail, idx,
 				   _("invalid shift operator"));
-		  return 0;
+		  return false;
 		}
 	      break;
 	    case AARCH64_OPND_QLF_MSL:
@@ -2892,7 +2892,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 		{
 		  set_other_error (mismatch_detail, idx,
 				   _("invalid shift operator"));
-		  return 0;
+		  return false;
 		}
 	      break;
 	    case AARCH64_OPND_QLF_NIL:
@@ -2900,12 +2900,12 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 		{
 		  set_other_error (mismatch_detail, idx,
 				   _("shift is not permitted"));
-		  return 0;
+		  return false;
 		}
 	      break;
 	    default:
 	      assert (0);
-	      return 0;
+	      return false;
 	    }
 	  /* Is the immediate valid?  */
 	  assert (idx == 1);
@@ -2915,7 +2915,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 	      if (!value_in_range_p (opnd->imm.value, -128, 255))
 		{
 		  set_imm_out_of_range_error (mismatch_detail, idx, -128, 255);
-		  return 0;
+		  return false;
 		}
 	    }
 	  else if (aarch64_shrink_expanded_imm8 (opnd->imm.value) < 0)
@@ -2925,7 +2925,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 		 ffffffffgggggggghhhhhhhh'.  */
 	      set_other_error (mismatch_detail, idx,
 			       _("invalid value for immediate"));
-	      return 0;
+	      return false;
 	    }
 	  /* Is the shift amount valid?  */
 	  switch (opnd->shifter.kind)
@@ -2936,12 +2936,12 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 		{
 		  set_sft_amount_out_of_range_error (mismatch_detail, idx, 0,
 						     (size - 1) * 8);
-		  return 0;
+		  return false;
 		}
 	      if (!value_aligned_p (opnd->shifter.amount, 8))
 		{
 		  set_unaligned_error (mismatch_detail, idx, 8);
-		  return 0;
+		  return false;
 		}
 	      break;
 	    case AARCH64_MOD_MSL:
@@ -2950,7 +2950,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 		{
 		  set_other_error (mismatch_detail, idx,
 				   _("shift amount must be 0 or 16"));
-		  return 0;
+		  return false;
 		}
 	      break;
 	    default:
@@ -2958,7 +2958,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 		{
 		  set_other_error (mismatch_detail, idx,
 				   _("invalid shift operator"));
-		  return 0;
+		  return false;
 		}
 	      break;
 	    }
@@ -2971,7 +2971,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 	    {
 	      set_other_error (mismatch_detail, idx,
 			       _("floating-point immediate expected"));
-	      return 0;
+	      return false;
 	    }
 	  /* The value is expected to be an 8-bit floating-point constant with
 	     sign, 3-bit exponent and normalized 4 bits of precision, encoded
@@ -2981,13 +2981,13 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 	    {
 	      set_other_error (mismatch_detail, idx,
 			       _("immediate out of range"));
-	      return 0;
+	      return false;
 	    }
 	  if (opnd->shifter.kind != AARCH64_MOD_NONE)
 	    {
 	      set_other_error (mismatch_detail, idx,
 			       _("invalid shift operator"));
-	      return 0;
+	      return false;
 	    }
 	  break;
 
@@ -3006,7 +3006,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 		  set_other_error (mismatch_detail, idx,
 				   _("no shift amount allowed for"
 				     " 8-bit constants"));
-		  return 0;
+		  return false;
 		}
 	    }
 	  else
@@ -3015,7 +3015,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 		{
 		  set_other_error (mismatch_detail, idx,
 				   _("shift amount must be 0 or 8"));
-		  return 0;
+		  return false;
 		}
 	      if (shift == 0 && (uvalue & 0xff) == 0)
 		{
@@ -3028,14 +3028,14 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 	    {
 	      set_other_error (mismatch_detail, idx,
 			       _("immediate too big for element size"));
-	      return 0;
+	      return false;
 	    }
 	  uvalue = (uvalue - min_value) & mask;
 	  if (uvalue > 0xff)
 	    {
 	      set_other_error (mismatch_detail, idx,
 			       _("invalid arithmetic immediate"));
-	      return 0;
+	      return false;
 	    }
 	  break;
 
@@ -3049,7 +3049,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 	    {
 	      set_other_error (mismatch_detail, idx,
 			       _("floating-point value must be 0.5 or 1.0"));
-	      return 0;
+	      return false;
 	    }
 	  break;
 
@@ -3059,7 +3059,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 	    {
 	      set_other_error (mismatch_detail, idx,
 			       _("floating-point value must be 0.5 or 2.0"));
-	      return 0;
+	      return false;
 	    }
 	  break;
 
@@ -3069,7 +3069,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 	    {
 	      set_other_error (mismatch_detail, idx,
 			       _("floating-point value must be 0.0 or 1.0"));
-	      return 0;
+	      return false;
 	    }
 	  break;
 
@@ -3081,7 +3081,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 	      {
 		set_other_error (mismatch_detail, idx,
 				 _("immediate out of range"));
-		return 0;
+		return false;
 	      }
 	  }
 	  break;
@@ -3094,13 +3094,13 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 	      {
 		set_other_error (mismatch_detail, idx,
 				 _("immediate out of range"));
-		return 0;
+		return false;
 	      }
 	    if (!aarch64_sve_dupm_mov_immediate_p (uimm, esize))
 	      {
 		set_other_error (mismatch_detail, idx,
 				 _("invalid replicated MOV immediate"));
-		return 0;
+		return false;
 	      }
 	  }
 	  break;
@@ -3110,7 +3110,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 	  if (!value_in_range_p (opnd->shifter.amount, 1, 16))
 	    {
 	      set_multiplier_out_of_range_error (mismatch_detail, idx, 1, 16);
-	      return 0;
+	      return false;
 	    }
 	  break;
 
@@ -3122,7 +3122,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 	    {
 	      set_imm_out_of_range_error (mismatch_detail, idx,
 					  0, 8 * size - 1);
-	      return 0;
+	      return false;
 	    }
 	  break;
 
@@ -3131,7 +3131,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 	  if (!value_in_range_p (opnd->imm.value, 1, size))
 	    {
 	      set_imm_out_of_range_error (mismatch_detail, idx, 1, size);
-	      return 0;
+	      return false;
 	    }
 	  break;
 
@@ -3144,7 +3144,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 	  if (!value_in_range_p (opnd->imm.value, 1, 8 * size))
 	    {
 	      set_imm_out_of_range_error (mismatch_detail, idx, 1, 8*size);
-	      return 0;
+	      return false;
 	    }
 	  break;
 
@@ -3152,13 +3152,13 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 	  if (!value_in_range_p (opnd->imm.value, 0, 56))
 	    {
 	      set_elem_idx_out_of_range_error (mismatch_detail, idx, 0, 56);
-	      return 0;
+	      return false;
 	    }
 	  if (opnd->imm.value % 8 != 0)
 	    {
 	      set_other_error (mismatch_detail, idx,
 			       _("byte index must be a multiple of 8"));
-	      return 0;
+	      return false;
 	    }
 	  break;
 
@@ -3188,7 +3188,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 	  if (opnds[1].imm.value < 0 || opnds[1].imm.value > max_value)
 	    {
 	      set_imm_out_of_range_error (mismatch_detail, 1, 0, max_value);
-	      return 0;
+	      return false;
 	    }
 	  break;
 	case AARCH64_OPND_PRFOP:
@@ -3197,7 +3197,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 	      set_other_error (mismatch_detail, idx,
 			       _("the register-index form of PRFM does"
 				 " not accept opcodes in the range 24-31"));
-	      return 0;
+	      return false;
 	    }
 	  break;
 	default:
@@ -3229,7 +3229,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
       if (!value_in_range_p (opnd->reglane.index, 0, num))
 	{
 	  set_elem_idx_out_of_range_error (mismatch_detail, idx, 0, num);
-	  return 0;
+	  return false;
 	}
       /* SMLAL<Q> <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Ts>[<index>].
 	 <Vm>	Is the vector register (V0-V31) or (V0-V15), whose
@@ -3245,7 +3245,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 	  && !value_in_range_p (opnd->reglane.regno, 0, 15))
 	{
 	  set_regno_out_of_range_error (mismatch_detail, idx, 0, 15);
-	  return 0;
+	  return false;
 	}
       if (type == AARCH64_OPND_Em8
 	  && !value_in_range_p (opnd->reglane.regno, 0, 7))
@@ -3265,7 +3265,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 	    {
 	      set_other_error (mismatch_detail, idx,
 			       _("extend operator expected"));
-	      return 0;
+	      return false;
 	    }
 	  /* It is not optional unless at least one of "Rd" or "Rn" is '11111'
 	     (i.e. SP), in which case it defaults to LSL. The LSL alias is
@@ -3278,13 +3278,13 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 		{
 		  set_other_error (mismatch_detail, idx,
 				   _("missing extend operator"));
-		  return 0;
+		  return false;
 		}
 	      else if (opnd->shifter.kind == AARCH64_MOD_LSL)
 		{
 		  set_other_error (mismatch_detail, idx,
 				   _("'LSL' operator not allowed"));
-		  return 0;
+		  return false;
 		}
 	    }
 	  assert (opnd->shifter.operator_present	/* Default to LSL.  */
@@ -3292,7 +3292,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 	  if (!value_in_range_p (opnd->shifter.amount, 0, 4))
 	    {
 	      set_sft_amount_out_of_range_error (mismatch_detail, idx, 0, 4);
-	      return 0;
+	      return false;
 	    }
 	  /* In the 64-bit form, the final register operand is written as Wm
 	     for all but the (possibly omitted) UXTX/LSL and SXTX
@@ -3305,7 +3305,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 	      && opnd->shifter.kind != AARCH64_MOD_SXTX)
 	    {
 	      set_other_error (mismatch_detail, idx, _("W register expected"));
-	      return 0;
+	      return false;
 	    }
 	  break;
 
@@ -3316,20 +3316,20 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 	    {
 	      set_other_error (mismatch_detail, idx,
 			       _("shift operator expected"));
-	      return 0;
+	      return false;
 	    }
 	  if (opnd->shifter.kind == AARCH64_MOD_ROR
 	      && opcode->iclass != log_shift)
 	    {
 	      set_other_error (mismatch_detail, idx,
 			       _("'ROR' operator not allowed"));
-	      return 0;
+	      return false;
 	    }
 	  num = qualifier == AARCH64_OPND_QLF_W ? 31 : 63;
 	  if (!value_in_range_p (opnd->shifter.amount, 0, num))
 	    {
 	      set_sft_amount_out_of_range_error (mismatch_detail, idx, 0, num);
-	      return 0;
+	      return false;
 	    }
 	  break;
 
@@ -3340,7 +3340,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 	  if (!value_in_range_p (opnd->shifter.amount, 0, 7))
 	    {
 	      set_sft_amount_out_of_range_error (mismatch_detail, idx, 0, 7);
-	      return 0;
+	      return false;
 	    }
 	  break;
 
@@ -3353,7 +3353,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
       break;
     }
 
-  return 1;
+  return true;
 }
 
 /* Main entrypoint for the operand constraint checking.
@@ -3367,7 +3367,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 
    Un-determined operand qualifiers may get established during the process.  */
 
-int
+bool
 aarch64_match_operands_constraint (aarch64_inst *inst,
 				   aarch64_operand_error *mismatch_detail)
 {
@@ -3397,7 +3397,7 @@ aarch64_match_operands_constraint (aarch64_inst *inst,
                   mismatch_detail->kind = AARCH64_OPDE_UNTIED_IMMS;
                   mismatch_detail->index = i;
                 }
-              return 0;
+              return false;
             }
           break;
 
@@ -3429,7 +3429,7 @@ aarch64_match_operands_constraint (aarch64_inst *inst,
 		    mismatch_detail->index = i;
 		    mismatch_detail->error = NULL;
 		  }
-		return 0;
+		return false;
 	      }
 	    break;
 	  }
@@ -3461,7 +3461,7 @@ aarch64_match_operands_constraint (aarch64_inst *inst,
 	  mismatch_detail->error = NULL;
 	  mismatch_detail->data[0].i = invalid_count;
 	}
-      return 0;
+      return false;
     }
 
   /* Match operands' constraint.  */
@@ -3475,17 +3475,17 @@ aarch64_match_operands_constraint (aarch64_inst *inst,
 	  DEBUG_TRACE ("skip the incomplete operand %d", i);
 	  continue;
 	}
-      if (operand_general_constraint_met_p (inst->operands, i, type,
-					    inst->opcode, mismatch_detail) == 0)
+      if (!operand_general_constraint_met_p (inst->operands, i, type,
+					     inst->opcode, mismatch_detail))
 	{
 	  DEBUG_TRACE ("FAIL on operand %d", i);
-	  return 0;
+	  return false;
 	}
     }
 
   DEBUG_TRACE ("PASS");
 
-  return 1;
+  return true;
 }
 
 /* Replace INST->OPCODE with OPCODE and return the replaced OPCODE.
diff --git a/opcodes/aarch64-opc.h b/opcodes/aarch64-opc.h
index e97ea5d27f2..c4cb6003b4c 100644
--- a/opcodes/aarch64-opc.h
+++ b/opcodes/aarch64-opc.h
@@ -436,7 +436,7 @@ get_operand_from_code (enum aarch64_opnd code)
 \f
 /* Operand qualifier and operand constraint checking.  */
 
-int aarch64_match_operands_constraint (aarch64_inst *,
+bool aarch64_match_operands_constraint (aarch64_inst *,
 				       aarch64_operand_error *);
 
 /* Operand qualifier related functions.  */

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH v0 04/13] aarch64: improve debuggability on array of enum
  2024-07-08 12:34 [PATCH v0 00/13] aarch64: add instructions for Armv9.5-A PAC enhancement Matthieu Longo
                   ` (2 preceding siblings ...)
  2024-07-08 12:34 ` [PATCH v0 03/13] aarch64: change returned type to bool to match semantic of functions Matthieu Longo
@ 2024-07-08 12:34 ` Matthieu Longo
  2024-07-08 12:34 ` [PATCH v0 05/13] aarch64: remove redundant register type R_N Matthieu Longo
                   ` (8 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: Matthieu Longo @ 2024-07-08 12:34 UTC (permalink / raw)
  To: binutils; +Cc: Richard Earnshaw, Nick Clifton, Matthieu Longo

[-- Attachment #1: Type: text/plain, Size: 699 bytes --]


The current space optmization on enum aarch64_opn_qualifier forced its
encoding using an unsigned char. This "hard-coded" optimization has the
bad consequence of making the array of such enums being completely
unreadable when debugging with GDB because the enum type is lost along
the way.
Keeping this space optimization, and the enum type as well, is possible
when the declaration of the enum is tagged with attribute((packed)).
attribute((packed)) is a GNU extension, and is wrapped in the macro
ATTRIBUTE_PACKED (defined in ansidecl.h), and should be used instead.
---
 include/opcode/aarch64.h | 6 +++---
 opcodes/aarch64-opc.c    | 6 +++---
 2 files changed, 6 insertions(+), 6 deletions(-)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: v0-0004-aarch64-improve-debuggability-on-array-of-enum.patch --]
[-- Type: text/x-patch; name="v0-0004-aarch64-improve-debuggability-on-array-of-enum.patch", Size: 1932 bytes --]

diff --git a/include/opcode/aarch64.h b/include/opcode/aarch64.h
index 61e31cc53f6..292d9c968d3 100644
--- a/include/opcode/aarch64.h
+++ b/include/opcode/aarch64.h
@@ -976,7 +976,7 @@ enum aarch64_opnd_qualifier
 
   /* Special qualifier used for indicating error in qualifier retrieval.  */
   AARCH64_OPND_QLF_ERR,
-};
+} ATTRIBUTE_PACKED;
 \f
 /* Instruction class.  */
 
@@ -1225,8 +1225,8 @@ enum err_type
 #define AARCH64_MAX_OPND_NUM 7
 /* Maximum number of qualifier sequences an instruction can have.  */
 #define AARCH64_MAX_QLF_SEQ_NUM 10
-/* Operand qualifier typedef; optimized for the size.  */
-typedef unsigned char aarch64_opnd_qualifier_t;
+/* Operand qualifier typedef  */
+typedef enum aarch64_opnd_qualifier aarch64_opnd_qualifier_t;
 /* Operand qualifier sequence typedef.  */
 typedef aarch64_opnd_qualifier_t	\
 	  aarch64_opnd_qualifier_seq_t [AARCH64_MAX_OPND_NUM];
diff --git a/opcodes/aarch64-opc.c b/opcodes/aarch64-opc.c
index 437e125c46d..5ac2277e102 100644
--- a/opcodes/aarch64-opc.c
+++ b/opcodes/aarch64-opc.c
@@ -762,9 +762,9 @@ aarch64_get_expected_qualifier (const aarch64_opnd_qualifier_seq_t *qseq_list,
      it can mean no qualifier for the operand, or the qualifer sequence is
      not in use (when all qualifiers in the sequence are NILs), we have to
      handle this special case here.  */
-  if (known_qlf == AARCH64_OPND_NIL)
+  if (((enum aarch64_opnd) known_qlf) == AARCH64_OPND_NIL)
     {
-      assert (qseq_list[0][known_idx] == AARCH64_OPND_NIL);
+      assert (((enum aarch64_opnd) qseq_list[0][known_idx]) == AARCH64_OPND_NIL);
       return qseq_list[0][idx];
     }
 
@@ -775,7 +775,7 @@ aarch64_get_expected_qualifier (const aarch64_opnd_qualifier_seq_t *qseq_list,
 	  if (saved_i != -1)
 	    /* More than one sequences are found to have KNOWN_QLF at
 	       KNOWN_IDX.  */
-	    return AARCH64_OPND_NIL;
+	    return AARCH64_OPND_QLF_NIL;
 	  saved_i = i;
 	}
     }

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH v0 05/13] aarch64: remove redundant register type R_N
  2024-07-08 12:34 [PATCH v0 00/13] aarch64: add instructions for Armv9.5-A PAC enhancement Matthieu Longo
                   ` (3 preceding siblings ...)
  2024-07-08 12:34 ` [PATCH v0 04/13] aarch64: improve debuggability on array of enum Matthieu Longo
@ 2024-07-08 12:34 ` Matthieu Longo
  2024-07-08 12:34 ` [PATCH v0 06/13] aarch64: testsuite: remove hard-coded instruction addresses Matthieu Longo
                   ` (7 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: Matthieu Longo @ 2024-07-08 12:34 UTC (permalink / raw)
  To: binutils; +Cc: Richard Earnshaw, Nick Clifton, Matthieu Longo

[-- Attachment #1: Type: text/plain, Size: 197 bytes --]


The register type R_N is redundant with R_ZR_SP. This patch removes it,
and replaces its usage by R_ZR_SP.
---
 gas/config/tc-aarch64.c | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: v0-0005-aarch64-remove-redundant-register-type-R_N.patch --]
[-- Type: text/x-patch; name="v0-0005-aarch64-remove-redundant-register-type-R_N.patch", Size: 971 bytes --]

diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c
index 7ee29cc8562..d5ce1421a69 100644
--- a/gas/config/tc-aarch64.c
+++ b/gas/config/tc-aarch64.c
@@ -344,10 +344,6 @@ struct reloc_entry
 		 | REG_TYPE(FP_B) | REG_TYPE(FP_H)			\
 		 | REG_TYPE(FP_S) | REG_TYPE(FP_D) | REG_TYPE(FP_Q)	\
 		 | REG_TYPE(Z) | REG_TYPE(P) | REG_TYPE(PN))		\
-  /* Any integer register; used for error messages only.  */		\
-  MULTI_REG_TYPE(R_N, REG_TYPE(R_32) | REG_TYPE(R_64)			\
-		 | REG_TYPE(SP_32) | REG_TYPE(SP_64)			\
-		 | REG_TYPE(ZR_32) | REG_TYPE(ZR_64))			\
   /* Any vector register.  */						\
   MULTI_REG_TYPE(VZ, REG_TYPE(V) | REG_TYPE(Z))				\
   /* An SVE vector or predicate register.  */				\
@@ -4631,7 +4627,7 @@ static bool
 parse_sme_immediate (char **str, int64_t *imm)
 {
   int64_t val;
-  if (! parse_constant_immediate (str, &val, REG_TYPE_R_N))
+  if (! parse_constant_immediate (str, &val, REG_TYPE_R_ZR_SP))
     return false;
 
   *imm = val;

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH v0 06/13] aarch64: testsuite: remove hard-coded instruction addresses
  2024-07-08 12:34 [PATCH v0 00/13] aarch64: add instructions for Armv9.5-A PAC enhancement Matthieu Longo
                   ` (4 preceding siblings ...)
  2024-07-08 12:34 ` [PATCH v0 05/13] aarch64: remove redundant register type R_N Matthieu Longo
@ 2024-07-08 12:34 ` Matthieu Longo
  2024-07-08 12:34 ` [PATCH v0 07/13] aarch64: refactor binary approach for RA signing method to make it extendable Matthieu Longo
                   ` (6 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: Matthieu Longo @ 2024-07-08 12:34 UTC (permalink / raw)
  To: binutils; +Cc: Richard Earnshaw, Nick Clifton, Matthieu Longo

[-- Attachment #1: Type: text/plain, Size: 128 bytes --]

---
 gas/testsuite/gas/aarch64/system-3.d | 52 ++++++++++++++--------------
 1 file changed, 26 insertions(+), 26 deletions(-)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: v0-0006-aarch64-testsuite-remove-hard-coded-instruction-a.patch --]
[-- Type: text/x-patch; name="v0-0006-aarch64-testsuite-remove-hard-coded-instruction-a.patch", Size: 1539 bytes --]

diff --git a/gas/testsuite/gas/aarch64/system-3.d b/gas/testsuite/gas/aarch64/system-3.d
index fc599cb11f8..04df1ee5cbf 100644
--- a/gas/testsuite/gas/aarch64/system-3.d
+++ b/gas/testsuite/gas/aarch64/system-3.d
@@ -6,29 +6,29 @@
 Disassembly of section \.text:
 
 0+ <.*>:
-   0:	d50320ff 	xpaclri
-   4:	d50320ff 	xpaclri
-   8:	d503211f 	pacia1716
-   c:	d503211f 	pacia1716
-  10:	d503215f 	pacib1716
-  14:	d503215f 	pacib1716
-  18:	d503219f 	autia1716
-  1c:	d503219f 	autia1716
-  20:	d50321df 	autib1716
-  24:	d50321df 	autib1716
-  28:	d503231f 	paciaz
-  2c:	d503231f 	paciaz
-  30:	d503233f 	paciasp
-  34:	d503233f 	paciasp
-  38:	d503235f 	pacibz
-  3c:	d503235f 	pacibz
-  40:	d503237f 	pacibsp
-  44:	d503237f 	pacibsp
-  48:	d503239f 	autiaz
-  4c:	d503239f 	autiaz
-  50:	d50323bf 	autiasp
-  54:	d50323bf 	autiasp
-  58:	d50323df 	autibz
-  5c:	d50323df 	autibz
-  60:	d50323ff 	autibsp
-  64:	d50323ff 	autibsp
+.*:	d50320ff 	xpaclri
+.*:	d50320ff 	xpaclri
+.*:	d503211f 	pacia1716
+.*:	d503211f 	pacia1716
+.*:	d503215f 	pacib1716
+.*:	d503215f 	pacib1716
+.*:	d503219f 	autia1716
+.*:	d503219f 	autia1716
+.*:	d50321df 	autib1716
+.*:	d50321df 	autib1716
+.*:	d503231f 	paciaz
+.*:	d503231f 	paciaz
+.*:	d503233f 	paciasp
+.*:	d503233f 	paciasp
+.*:	d503235f 	pacibz
+.*:	d503235f 	pacibz
+.*:	d503237f 	pacibsp
+.*:	d503237f 	pacibsp
+.*:	d503239f 	autiaz
+.*:	d503239f 	autiaz
+.*:	d50323bf 	autiasp
+.*:	d50323bf 	autiasp
+.*:	d50323df 	autibz
+.*:	d50323df 	autibz
+.*:	d50323ff 	autibsp
+.*:	d50323ff 	autibsp

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH v0 07/13] aarch64: refactor binary approach for RA signing method to make it extendable
  2024-07-08 12:34 [PATCH v0 00/13] aarch64: add instructions for Armv9.5-A PAC enhancement Matthieu Longo
                   ` (5 preceding siblings ...)
  2024-07-08 12:34 ` [PATCH v0 06/13] aarch64: testsuite: remove hard-coded instruction addresses Matthieu Longo
@ 2024-07-08 12:34 ` Matthieu Longo
  2024-07-08 12:34 ` [PATCH v0 08/13] aarch64: add PAuth_LR instructions belonging to NOP space Matthieu Longo
                   ` (5 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: Matthieu Longo @ 2024-07-08 12:34 UTC (permalink / raw)
  To: binutils; +Cc: Richard Earnshaw, Nick Clifton, Matthieu Longo

[-- Attachment #1: Type: text/plain, Size: 168 bytes --]

---
 gas/gen-sframe.c | 21 +++++++++++++--------
 gas/gen-sframe.h | 14 +++++++++++---
 include/sframe.h |  4 ++--
 3 files changed, 26 insertions(+), 13 deletions(-)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: v0-0007-aarch64-refactor-binary-approach-for-RA-signing-m.patch --]
[-- Type: text/x-patch; name="v0-0007-aarch64-refactor-binary-approach-for-RA-signing-m.patch", Size: 4733 bytes --]

diff --git a/gas/gen-sframe.c b/gas/gen-sframe.c
index 626dc33b71d..247b65a37d0 100644
--- a/gas/gen-sframe.c
+++ b/gas/gen-sframe.c
@@ -254,11 +254,12 @@ static struct sframe_version_ops sframe_ver_ops;
 
 static unsigned char
 sframe_v1_set_fre_info (unsigned int base_reg, unsigned int num_offsets,
-			unsigned int offset_size, bool mangled_ra_p)
+			unsigned int offset_size,
+			RA_signing_method_t ra_signing_info)
 {
   unsigned char fre_info;
   fre_info = SFRAME_V1_FRE_INFO (base_reg, num_offsets, offset_size);
-  fre_info = SFRAME_V1_FRE_INFO_UPDATE_MANGLED_RA_P (mangled_ra_p, fre_info);
+  fre_info = SFRAME_V1_FRE_INFO_UPDATE_RA_SIGNING_INFO (ra_signing_info, fre_info);
   return fre_info;
 }
 
@@ -292,10 +293,11 @@ sframe_set_version (uint32_t sframe_version ATTRIBUTE_UNUSED)
 
 static unsigned char
 sframe_set_fre_info (unsigned int base_reg, unsigned int num_offsets,
-		     unsigned int offset_size, bool mangled_ra_p)
+		     unsigned int offset_size,
+		     RA_signing_method_t ra_signing_info)
 {
   return sframe_ver_ops.set_fre_info (base_reg, num_offsets,
-				      offset_size, mangled_ra_p);
+				      offset_size, ra_signing_info);
 }
 
 /* SFrame set func info. */
@@ -526,7 +528,7 @@ output_sframe_row_entry (symbolS *fde_start_addr,
   fre_num_offsets = get_fre_num_offsets (sframe_fre);
   fre_offset_size = sframe_get_fre_offset_size (sframe_fre);
   fre_info = sframe_set_fre_info (fre_base_reg, fre_num_offsets,
-				  fre_offset_size, sframe_fre->mangled_ra_p);
+				  fre_offset_size, sframe_fre->ra_signing_info);
   out_one (fre_info);
 
   idx = sframe_fre_offset_func_map_index (fre_offset_size);
@@ -879,7 +881,7 @@ sframe_row_entry_new (void)
   fre->merge_candidate = true;
   /* Reset the mangled RA status bit to zero by default.  We will initialize it in
      sframe_row_entry_initialize () with the sticky bit if set.  */
-  fre->mangled_ra_p = false;
+  fre->ra_signing_info = RA_no_signing;
 
   return fre;
 }
@@ -927,7 +929,7 @@ sframe_row_entry_initialize (struct sframe_row_entry *cur_fre,
   cur_fre->ra_offset = prev_fre->ra_offset;
   /* Treat RA mangling as a sticky bit.  It retains its value until another
      .cfi_negate_ra_state is seen.  */
-  cur_fre->mangled_ra_p = prev_fre->mangled_ra_p;
+  cur_fre->ra_signing_info = prev_fre->ra_signing_info;
 }
 
 /* Return SFrame register name for SP, FP, and RA, or NULL if other.  */
@@ -1276,7 +1278,10 @@ sframe_xlate_do_aarch64_negate_ra_state (struct sframe_xlate_ctx *xlate_ctx,
 
   gas_assert (cur_fre);
   /* Toggle the mangled RA status bit.  */
-  cur_fre->mangled_ra_p = !cur_fre->mangled_ra_p;
+  cur_fre->ra_signing_info
+    = ((cur_fre->ra_signing_info == RA_no_signing)
+       ? RA_signing_SP
+       : RA_no_signing);
   cur_fre->merge_candidate = false;
 
   return SFRAME_XLATE_OK;
diff --git a/gas/gen-sframe.h b/gas/gen-sframe.h
index 8ed46dbb087..db1e5de968f 100644
--- a/gas/gen-sframe.h
+++ b/gas/gen-sframe.h
@@ -21,6 +21,8 @@
 #ifndef GENSFRAME_H
 #define GENSFRAME_H
 
+#include "ansidecl.h"
+
 #define SFRAME_FRE_ELEM_LOC_REG		0
 #define SFRAME_FRE_ELEM_LOC_STACK	1
 
@@ -39,6 +41,12 @@
    the RA.
 */
 
+typedef enum ATTRIBUTE_PACKED
+{
+  RA_no_signing = 0x0,
+  RA_signing_SP = 0x1,
+} RA_signing_method_t;
+
 struct sframe_row_entry
 {
   /* A linked list.  */
@@ -52,8 +60,8 @@ struct sframe_row_entry
      on it.  */
   bool merge_candidate;
 
-  /* Whether the return address is mangled with pauth code.  */
-  bool mangled_ra_p;
+  /* Track the PAuth mangling information for RA.  */
+  RA_signing_method_t ra_signing_info;
 
   /* Track CFA base (architectural) register ID.  */
   unsigned int cfa_base_reg;
@@ -146,7 +154,7 @@ struct sframe_version_ops
   unsigned char format_version;    /* SFrame format version.  */
   /* set SFrame FRE info.  */
   unsigned char (*set_fre_info) (unsigned int, unsigned int, unsigned int,
-				 bool);
+				 RA_signing_method_t);
   /* set SFrame Func info.  */
   unsigned char (*set_func_info) (unsigned int, unsigned int, unsigned int);
 };
diff --git a/include/sframe.h b/include/sframe.h
index b3d0c2e937d..53388aaaa91 100644
--- a/include/sframe.h
+++ b/include/sframe.h
@@ -264,8 +264,8 @@ typedef struct sframe_fre_info
    (((offset_num) & 0xf) << 1) | ((base_reg_id) & 0x1))
 
 /* Set the mangled_ra_p bit as indicated.  */
-#define SFRAME_V1_FRE_INFO_UPDATE_MANGLED_RA_P(mangled_ra_p, fre_info) \
-  ((((mangled_ra_p) & 0x1) << 7) | ((fre_info) & 0x7f))
+#define SFRAME_V1_FRE_INFO_UPDATE_RA_SIGNING_INFO(ra_signing_info, fre_info) \
+  ((((ra_signing_info) & 0x1) << 7) | ((fre_info) & 0x7f))
 
 #define SFRAME_V1_FRE_CFA_BASE_REG_ID(data)	  ((data) & 0x1)
 #define SFRAME_V1_FRE_OFFSET_COUNT(data)	  (((data) >> 1) & 0xf)

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH v0 08/13] aarch64: add PAuth_LR instructions belonging to NOP space
  2024-07-08 12:34 [PATCH v0 00/13] aarch64: add instructions for Armv9.5-A PAC enhancement Matthieu Longo
                   ` (6 preceding siblings ...)
  2024-07-08 12:34 ` [PATCH v0 07/13] aarch64: refactor binary approach for RA signing method to make it extendable Matthieu Longo
@ 2024-07-08 12:34 ` Matthieu Longo
  2024-07-08 12:34 ` [PATCH v0 09/13] aarch64: add pauth-lr feature option for Armv9.5-A PAC enhancements Matthieu Longo
                   ` (4 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: Matthieu Longo @ 2024-07-08 12:34 UTC (permalink / raw)
  To: binutils; +Cc: Richard Earnshaw, Nick Clifton, Matthieu Longo

[-- Attachment #1: Type: text/plain, Size: 472 bytes --]


The 'pacm' instruction is introduced by the PAC enhancement feature
PAuth_LR, but does not require the declaration of this feature
because it belongs to the NOP space.
This patch also adds the relevant tests for the 'pacm' instruction.
---
 gas/testsuite/gas/aarch64/system-3.d | 2 ++
 gas/testsuite/gas/aarch64/system-3.s | 4 ++++
 gas/testsuite/gas/aarch64/system.d   | 2 +-
 opcodes/aarch64-tbl.h                | 1 +
 4 files changed, 8 insertions(+), 1 deletion(-)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: v0-0008-aarch64-add-PAuth_LR-instructions-belonging-to-NO.patch --]
[-- Type: text/x-patch; name="v0-0008-aarch64-add-PAuth_LR-instructions-belonging-to-NO.patch", Size: 2049 bytes --]

diff --git a/gas/testsuite/gas/aarch64/system-3.d b/gas/testsuite/gas/aarch64/system-3.d
index 04df1ee5cbf..4b5dae23d03 100644
--- a/gas/testsuite/gas/aarch64/system-3.d
+++ b/gas/testsuite/gas/aarch64/system-3.d
@@ -32,3 +32,5 @@ Disassembly of section \.text:
 .*:	d50323df 	autibz
 .*:	d50323ff 	autibsp
 .*:	d50323ff 	autibsp
+.*:	d50324ff 	pacm
+.*:	d50324ff 	pacm
diff --git a/gas/testsuite/gas/aarch64/system-3.s b/gas/testsuite/gas/aarch64/system-3.s
index c68b4a8e09d..319bf66cf40 100644
--- a/gas/testsuite/gas/aarch64/system-3.s
+++ b/gas/testsuite/gas/aarch64/system-3.s
@@ -39,3 +39,7 @@
 
 	autibsp
 	hint #0x1f
+
+	/* ARMv9.5 Pointer Authentication, HINT alias instructions. */
+	pacm
+	hint #0x27
diff --git a/gas/testsuite/gas/aarch64/system.d b/gas/testsuite/gas/aarch64/system.d
index c1400771d43..30db45b8ff1 100644
--- a/gas/testsuite/gas/aarch64/system.d
+++ b/gas/testsuite/gas/aarch64/system.d
@@ -54,7 +54,7 @@ Disassembly of section \.text:
 .*:	d503249f 	(hint	#0x24|bti	j)
 .*:	d50324bf 	hint	#0x25
 .*:	d50324df 	(hint	#0x26|bti	jc)
-.*:	d50324ff 	hint	#0x27
+.*:	d50324ff 	(hint	#0x27|pacm)
 .*:	d503251f 	(hint	#0x28|chkfeat	x16)
 .*:	d503253f 	hint	#0x29
 .*:	d503255f 	hint	#0x2a
diff --git a/opcodes/aarch64-tbl.h b/opcodes/aarch64-tbl.h
index 7ef9cea9119..dd9f2b6c6cd 100644
--- a/opcodes/aarch64-tbl.h
+++ b/opcodes/aarch64-tbl.h
@@ -4527,6 +4527,7 @@ const struct aarch64_opcode aarch64_opcode_table[] =
   CORE_INSN ("pacib1716", 0xd503215f, 0xffffffff, ic_system, 0, OP0 (), {}, F_ALIAS),
   CORE_INSN ("autia1716", 0xd503219f, 0xffffffff, ic_system, 0, OP0 (), {}, F_ALIAS),
   CORE_INSN ("autib1716", 0xd50321df, 0xffffffff, ic_system, 0, OP0 (), {}, F_ALIAS),
+  CORE_INSN ("pacm", 0xd50324ff, 0xffffffff, ic_system, 0, OP0 (), {}, F_ALIAS),
   CORE_INSN ("esb", 0xd503221f, 0xffffffff, ic_system, 0, OP0 (), {}, F_ALIAS),
   CORE_INSN ("psb", 0xd503223f, 0xffffffff, ic_system, 0, OP1 (BARRIER_PSB), {}, F_ALIAS),
   CORE_INSN ("tsb", 0xd503225f, 0xffffffff, ic_system, 0, OP1 (BARRIER_PSB), {}, F_ALIAS),

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH v0 09/13] aarch64: add pauth-lr feature option for Armv9.5-A PAC enhancements
  2024-07-08 12:34 [PATCH v0 00/13] aarch64: add instructions for Armv9.5-A PAC enhancement Matthieu Longo
                   ` (7 preceding siblings ...)
  2024-07-08 12:34 ` [PATCH v0 08/13] aarch64: add PAuth_LR instructions belonging to NOP space Matthieu Longo
@ 2024-07-08 12:34 ` Matthieu Longo
  2024-07-08 12:34 ` [PATCH v0 10/13] aarch64: add PAuth_LR instructions with no or one-register operand Matthieu Longo
                   ` (3 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: Matthieu Longo @ 2024-07-08 12:34 UTC (permalink / raw)
  To: binutils; +Cc: Richard Earnshaw, Nick Clifton, Matthieu Longo

[-- Attachment #1: Type: text/plain, Size: 140 bytes --]

---
 gas/config/tc-aarch64.c  | 1 +
 include/opcode/aarch64.h | 2 ++
 opcodes/aarch64-tbl.h    | 5 +++++
 3 files changed, 8 insertions(+)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: v0-0009-aarch64-add-pauth-lr-feature-option-for-Armv9.5-A.patch --]
[-- Type: text/x-patch; name="v0-0009-aarch64-add-pauth-lr-feature-option-for-Armv9.5-A.patch", Size: 2725 bytes --]

diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c
index d5ce1421a69..0887d9a0736 100644
--- a/gas/config/tc-aarch64.c
+++ b/gas/config/tc-aarch64.c
@@ -10668,6 +10668,7 @@ static const struct aarch64_option_cpu_value_table aarch64_features[] = {
   {"flagm",		AARCH64_FEATURE (FLAGM), AARCH64_NO_FEATURES},
   {"flagm2",		AARCH64_FEATURE (FLAGMANIP), AARCH64_FEATURE (FLAGM)},
   {"pauth",		AARCH64_FEATURE (PAUTH), AARCH64_NO_FEATURES},
+  {"pauth-lr",		AARCH64_FEATURE (PAUTH_LR), AARCH64_FEATURE (PAUTH)},
   {"xs",		AARCH64_FEATURE (XS), AARCH64_NO_FEATURES},
   {"wfxt",		AARCH64_FEATURE (WFXT), AARCH64_NO_FEATURES},
   {"mops",		AARCH64_FEATURE (MOPS), AARCH64_NO_FEATURES},
diff --git a/include/opcode/aarch64.h b/include/opcode/aarch64.h
index 292d9c968d3..2710730e72e 100644
--- a/include/opcode/aarch64.h
+++ b/include/opcode/aarch64.h
@@ -72,6 +72,8 @@ enum aarch64_feature_bit {
   AARCH64_FEATURE_LS64,
   /* v8.3 Pointer Authentication.  */
   AARCH64_FEATURE_PAUTH,
+  /* v9.5 Pointer Authentication. */
+  AARCH64_FEATURE_PAUTH_LR,
   /* FP instructions.  */
   AARCH64_FEATURE_FP,
   /* SIMD instructions.  */
diff --git a/opcodes/aarch64-tbl.h b/opcodes/aarch64-tbl.h
index dd9f2b6c6cd..3ba2c088be8 100644
--- a/opcodes/aarch64-tbl.h
+++ b/opcodes/aarch64-tbl.h
@@ -2684,6 +2684,8 @@ static const aarch64_feature_set aarch64_feature_sve =
   AARCH64_FEATURE (SVE);
 static const aarch64_feature_set aarch64_feature_pauth =
   AARCH64_FEATURE (PAUTH);
+static const aarch64_feature_set aarch64_feature_pauth_lr =
+  AARCH64_FEATURES (2, PAUTH, PAUTH_LR);
 static const aarch64_feature_set aarch64_feature_compnum =
   AARCH64_FEATURE (COMPNUM);
 static const aarch64_feature_set aarch64_feature_jscvt =
@@ -2845,6 +2847,7 @@ static const aarch64_feature_set aarch64_feature_sme_f16f16_f8f16 =
 #define SIMD_F16	&aarch64_feature_simd_f16
 #define SVE		&aarch64_feature_sve
 #define PAUTH		&aarch64_feature_pauth
+#define PAUTH_LR	&aarch64_feature_pauth_lr
 #define COMPNUM		&aarch64_feature_compnum
 #define JSCVT		&aarch64_feature_jscvt
 #define RCPC		&aarch64_feature_rcpc
@@ -2950,6 +2953,8 @@ static const aarch64_feature_set aarch64_feature_sme_f16f16_f8f16 =
     FLAGS | F_STRICT, CONSTRAINTS, TIED, NULL }
 #define PAUTH_INSN(NAME,OPCODE,MASK,CLASS,OPS,QUALS,FLAGS) \
   { NAME, OPCODE, MASK, CLASS, 0, PAUTH, OPS, QUALS, FLAGS, 0, 0, NULL }
+#define PAUTH_LR_INSN(NAME,OPCODE,MASK,CLASS,OPS,QUALS,FLAGS) \
+  { NAME, OPCODE, MASK, CLASS, 0, PAUTH_LR, OPS, QUALS, FLAGS, 0, 0, NULL }
 #define CNUM_INSN(NAME,OPCODE,MASK,CLASS,OP,OPS,QUALS,FLAGS) \
   { NAME, OPCODE, MASK, CLASS, OP, COMPNUM, OPS, QUALS, FLAGS, 0, 0, NULL }
 #define JSCVT_INSN(NAME,OPCODE,MASK,CLASS,OPS,QUALS,FLAGS) \

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH v0 10/13] aarch64: add PAuth_LR instructions with no or one-register operand
  2024-07-08 12:34 [PATCH v0 00/13] aarch64: add instructions for Armv9.5-A PAC enhancement Matthieu Longo
                   ` (8 preceding siblings ...)
  2024-07-08 12:34 ` [PATCH v0 09/13] aarch64: add pauth-lr feature option for Armv9.5-A PAC enhancements Matthieu Longo
@ 2024-07-08 12:34 ` Matthieu Longo
  2024-07-08 12:34 ` [PATCH v0 11/13] aarch64: add flag OPD_F_UNSIGNED to distinguish signedness of immediate operands Matthieu Longo
                   ` (2 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: Matthieu Longo @ 2024-07-08 12:34 UTC (permalink / raw)
  To: binutils; +Cc: Richard Earnshaw, Nick Clifton, Matthieu Longo

[-- Attachment #1: Type: text/plain, Size: 1243 bytes --]


This patch adds the instructions required by Armv9.5-A PAC
enhancements.
- paci<k>sppc, pacnbi<>sppc, paci<k>171615, auti<k>171615
- the register variant of auti<k>sppc -> auti<k>sppcr
- the register variant of reta<k>sppc -> reta<k>sppcr
A new register type R was also added to prevent a misuse of SP or XZR
registers with the register variant instructions.
It also adds the relevant tests for those instructions.
---
 gas/config/tc-aarch64.c                  | 12 +++++++++-
 gas/testsuite/gas/aarch64/pauth_lr-bad.d |  3 +++
 gas/testsuite/gas/aarch64/pauth_lr-bad.l | 11 +++++++++
 gas/testsuite/gas/aarch64/pauth_lr-bad.s | 12 ++++++++++
 gas/testsuite/gas/aarch64/pauth_lr.d     | 24 +++++++++++++++++++
 gas/testsuite/gas/aarch64/pauth_lr.s     | 30 ++++++++++++++++++++++++
 include/opcode/aarch64.h                 |  1 +
 opcodes/aarch64-tbl.h                    | 18 ++++++++++++++
 8 files changed, 110 insertions(+), 1 deletion(-)
 create mode 100644 gas/testsuite/gas/aarch64/pauth_lr-bad.d
 create mode 100644 gas/testsuite/gas/aarch64/pauth_lr-bad.l
 create mode 100644 gas/testsuite/gas/aarch64/pauth_lr-bad.s
 create mode 100644 gas/testsuite/gas/aarch64/pauth_lr.d
 create mode 100644 gas/testsuite/gas/aarch64/pauth_lr.s


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: v0-0010-aarch64-add-PAuth_LR-instructions-with-no-or-one-.patch --]
[-- Type: text/x-patch; name="v0-0010-aarch64-add-PAuth_LR-instructions-with-no-or-one-.patch", Size: 7638 bytes --]

diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c
index 0887d9a0736..f69b0b0c0e2 100644
--- a/gas/config/tc-aarch64.c
+++ b/gas/config/tc-aarch64.c
@@ -306,6 +306,8 @@ struct reloc_entry
   /* Typecheck: same, plus SVE registers.  */				\
   MULTI_REG_TYPE(SVE_BASE, REG_TYPE(R_64) | REG_TYPE(SP_64)		\
 		 | REG_TYPE(Z))						\
+  /* Typecheck: x[0-30], w[0-30].  */					\
+  MULTI_REG_TYPE(R, REG_TYPE(R_32) | REG_TYPE(R_64))			\
   /* Typecheck: x[0-30], w[0-30] or [xw]zr.  */				\
   MULTI_REG_TYPE(R_ZR, REG_TYPE(R_32) | REG_TYPE(R_64)			\
 		 | REG_TYPE(ZR_32) | REG_TYPE(ZR_64))			\
@@ -6688,7 +6690,15 @@ parse_operands (char *str, const aarch64_opcode *opcode)
 	case AARCH64_OPND_PAIRREG:
 	case AARCH64_OPND_PAIRREG_OR_XZR:
 	case AARCH64_OPND_SVE_Rm:
-	  po_int_fp_reg_or_fail (REG_TYPE_R_ZR);
+	  switch (opcode->iclass)
+	  {
+	    case ic_pauth_lr:
+	      po_int_fp_reg_or_fail (REG_TYPE_R);
+	      break;
+	    default:
+	      po_int_fp_reg_or_fail (REG_TYPE_R_ZR);
+	      break;
+	  }
 
 	  /* In LS64 load/store instructions Rt register number must be even
 	     and <=22.  */
diff --git a/gas/testsuite/gas/aarch64/pauth_lr-bad.d b/gas/testsuite/gas/aarch64/pauth_lr-bad.d
new file mode 100644
index 00000000000..4ee0bfcaf35
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/pauth_lr-bad.d
@@ -0,0 +1,3 @@
+#source: pauth_lr-bad.s
+#as: -march=armv9.4-a+pauth-lr
+#error_output: pauth_lr-bad.l
\ No newline at end of file
diff --git a/gas/testsuite/gas/aarch64/pauth_lr-bad.l b/gas/testsuite/gas/aarch64/pauth_lr-bad.l
new file mode 100644
index 00000000000..d0a629f216f
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/pauth_lr-bad.l
@@ -0,0 +1,11 @@
+.*: Assembler messages:
+.*: Error: operand mismatch -- `autiasppcr w0'
+.*: Info:    did you mean this\?
+.*: Info:    	autiasppcr x0
+.*: Error: unexpected register type at operand 1 -- `autiasppcr sp'
+.*: Error: unexpected register type at operand 1 -- `autiasppcr xzr'
+.*: Error: operand mismatch -- `retaasppcr w0'
+.*: Info:    did you mean this\?
+.*: Info:    	retaasppcr x0
+.*: Error: unexpected register type at operand 1 -- `retaasppcr sp'
+.*: Error: unexpected register type at operand 1 -- `retaasppcr xzr'
\ No newline at end of file
diff --git a/gas/testsuite/gas/aarch64/pauth_lr-bad.s b/gas/testsuite/gas/aarch64/pauth_lr-bad.s
new file mode 100644
index 00000000000..98840d4c257
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/pauth_lr-bad.s
@@ -0,0 +1,12 @@
+	/* ARMv9.5 Pointer authentication instructions.  */
+	.text
+
+lr_signing:
+
+	autiasppcr w0 // 32-bit registers not allowed
+	autiasppcr sp // stack pointer register not allowed
+	autiasppcr xzr // zero register not allowed
+
+	retaasppcr w0 // 32-bit registers not allowed
+	retaasppcr sp // SP not allowed
+	retaasppcr xzr // zero register not allowed
diff --git a/gas/testsuite/gas/aarch64/pauth_lr.d b/gas/testsuite/gas/aarch64/pauth_lr.d
new file mode 100644
index 00000000000..ddd65b77fd1
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/pauth_lr.d
@@ -0,0 +1,24 @@
+#source: pauth_lr.s
+#as: -march=armv9.4-a+pauth-lr
+#objdump: -dr
+
+.*:     file .*
+
+Disassembly of section \.text:
+
+0+ <.*>:
+.*:	d50324ff 	pacm
+.*:	dac1a3fe 	paciasppc
+.*:	dac1a7fe 	pacibsppc
+.*:	dac18bfe 	pacia171615
+.*:	dac18ffe 	pacib171615
+.*:	dac183fe 	pacnbiasppc
+.*:	dac187fe 	pacnbibsppc
+.*:	dac1bbfe 	autia171615
+.*:	dac1bffe 	autib171615
+.*:	dac1901e 	autiasppcr	x0
+.*:	dac193de 	autiasppcr	x30
+.*:	dac1941e 	autibsppcr	x0
+.*:	d65f0be0 	retaasppcr	x0
+.*:	d65f0bfe 	retaasppcr	x30
+.*:	d65f0fe0 	retabsppcr	x0
\ No newline at end of file
diff --git a/gas/testsuite/gas/aarch64/pauth_lr.s b/gas/testsuite/gas/aarch64/pauth_lr.s
new file mode 100644
index 00000000000..cdedd6e4588
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/pauth_lr.s
@@ -0,0 +1,30 @@
+	/* ARMv9.5 Pointer authentication instructions.  */
+	.text
+
+	// only NOP-space instruction to enable ComputePAC2() with PAuth instructions.
+	pacm
+
+	// Signing of LR using SP and PC as deversifiers.
+	paciasppc
+	pacibsppc
+
+	pacia171615
+	pacib171615
+
+	// When used along feature FEAT_BTI
+	pacnbiasppc
+	pacnbibsppc
+
+	// Authenticating the PAC in the address in register LR
+	autia171615
+	autib171615
+
+	// Variant with value of PC passed by register
+	autiasppcr x0
+	autiasppcr x30
+	autibsppcr x0
+
+	// Authentication + return
+	retaasppcr x0
+	retaasppcr x30
+	retabsppcr x0
diff --git a/include/opcode/aarch64.h b/include/opcode/aarch64.h
index 2710730e72e..81c9b1f1220 100644
--- a/include/opcode/aarch64.h
+++ b/include/opcode/aarch64.h
@@ -1054,6 +1054,7 @@ enum aarch64_insn_class
   lse_atomic,
   lse128_atomic,
   movewide,
+  ic_pauth_lr,
   pcreladdr,
   ic_system,
   sme_fp_sd,
diff --git a/opcodes/aarch64-tbl.h b/opcodes/aarch64-tbl.h
index 3ba2c088be8..ef7b69e4970 100644
--- a/opcodes/aarch64-tbl.h
+++ b/opcodes/aarch64-tbl.h
@@ -1034,6 +1034,12 @@
   QLF4(V_16B, V_16B, V_16B, imm_0_15),	\
 }
 
+/* e.g. AUTI<k>SPPCR Xn  */
+#define QL_PAUTH_REG		\
+{				\
+  QLF1(X),			\
+}
+
 /* e.g. .  */
 #define QL_V3SAMEHS		\
 {				\
@@ -3888,6 +3894,8 @@ const struct aarch64_opcode aarch64_opcode_table[] =
   PAUTH_INSN ("retab", 0xd65f0fff, 0xffffffff, branch_reg, OP0 (), {}, 0),
   PAUTH_INSN ("eretaa", 0xd69f0bff, 0xffffffff, branch_reg, OP0 (), {}, 0),
   PAUTH_INSN ("eretab", 0xd69f0fff, 0xffffffff, branch_reg, OP0 (), {}, 0),
+  PAUTH_LR_INSN ("retaasppcr", 0xd65f0be0, 0xffffffe0, ic_pauth_lr, OP1 (Rd), QL_PAUTH_REG, 0),
+  PAUTH_LR_INSN ("retabsppcr", 0xd65f0fe0, 0xffffffe0, ic_pauth_lr, OP1 (Rd), QL_PAUTH_REG, 0),
   /* Compare & branch (immediate).  */
   CORE_INSN ("cbz", 0x34000000, 0x7f000000, compbranch, 0, OP2 (Rt, ADDR_PCREL19), QL_R_PCREL, F_SF),
   CORE_INSN ("cbnz", 0x35000000, 0x7f000000, compbranch, 0, OP2 (Rt, ADDR_PCREL19), QL_R_PCREL, F_SF),
@@ -3939,10 +3947,20 @@ const struct aarch64_opcode aarch64_opcode_table[] =
   PAUTH_INSN ("pacib", 0xdac10400, 0xfffffc00, dp_1src, OP2 (Rd, Rn_SP), QL_I2SAMEX, 0),
   PAUTH_INSN ("pacda", 0xdac10800, 0xfffffc00, dp_1src, OP2 (Rd, Rn_SP), QL_I2SAMEX, 0),
   PAUTH_INSN ("pacdb", 0xdac10c00, 0xfffffc00, dp_1src, OP2 (Rd, Rn_SP), QL_I2SAMEX, 0),
+  PAUTH_LR_INSN ("paciasppc", 0xdac1a3fe, 0xffffffff, ic_system, OP0 (), {}, 0),
+  PAUTH_LR_INSN ("pacibsppc", 0xdac1a7fe, 0xffffffff, ic_system, OP0 (), {}, 0),
+  PAUTH_LR_INSN ("pacnbiasppc", 0xdac183fe, 0xffffffff, ic_system, OP0 (), {}, 0),
+  PAUTH_LR_INSN ("pacnbibsppc", 0xdac187fe, 0xffffffff, ic_system, OP0 (), {}, 0),
+  PAUTH_LR_INSN ("pacia171615", 0xdac18bfe, 0xffffffff, ic_system, OP0 (), {}, 0),
+  PAUTH_LR_INSN ("pacib171615", 0xdac18ffe, 0xffffffff, ic_system, OP0 (), {}, 0),
   PAUTH_INSN ("autia", 0xdac11000, 0xfffffc00, dp_1src, OP2 (Rd, Rn_SP), QL_I2SAMEX, 0),
   PAUTH_INSN ("autib", 0xdac11400, 0xfffffc00, dp_1src, OP2 (Rd, Rn_SP), QL_I2SAMEX, 0),
   PAUTH_INSN ("autda", 0xdac11800, 0xfffffc00, dp_1src, OP2 (Rd, Rn_SP), QL_I2SAMEX, 0),
   PAUTH_INSN ("autdb", 0xdac11c00, 0xfffffc00, dp_1src, OP2 (Rd, Rn_SP), QL_I2SAMEX, 0),
+  PAUTH_LR_INSN ("autiasppcr", 0xdac1901e, 0xfffffc1f, ic_pauth_lr, OP1 (Rn), QL_PAUTH_REG, 0),
+  PAUTH_LR_INSN ("autibsppcr", 0xdac1941e, 0xfffffc1f, ic_pauth_lr, OP1 (Rn), QL_PAUTH_REG, 0),
+  PAUTH_LR_INSN ("autia171615", 0xdac1bbfe, 0xffffffff, ic_system, OP0 (), {}, 0),
+  PAUTH_LR_INSN ("autib171615", 0xdac1bffe, 0xffffffff, ic_system, OP0 (), {}, 0),
   PAUTH_INSN ("paciza", 0xdac123e0, 0xffffffe0, dp_1src, OP1 (Rd), QL_I1X, 0),
   PAUTH_INSN ("pacizb", 0xdac127e0, 0xffffffe0, dp_1src, OP1 (Rd), QL_I1X, 0),
   PAUTH_INSN ("pacdza", 0xdac12be0, 0xffffffe0, dp_1src, OP1 (Rd), QL_I1X, 0),

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH v0 11/13] aarch64: add flag OPD_F_UNSIGNED to distinguish signedness of immediate operands
  2024-07-08 12:34 [PATCH v0 00/13] aarch64: add instructions for Armv9.5-A PAC enhancement Matthieu Longo
                   ` (9 preceding siblings ...)
  2024-07-08 12:34 ` [PATCH v0 10/13] aarch64: add PAuth_LR instructions with no or one-register operand Matthieu Longo
@ 2024-07-08 12:34 ` Matthieu Longo
  2024-07-08 12:34 ` [PATCH v0 12/13] aarch64: add PAuth_LR instructions with imm16 operand Matthieu Longo
  2024-07-08 12:34 ` [PATCH v0 13/13] aarch64: add DWARF CFI directive for PAuth_LR Matthieu Longo
  12 siblings, 0 replies; 14+ messages in thread
From: Matthieu Longo @ 2024-07-08 12:34 UTC (permalink / raw)
  To: binutils; +Cc: Richard Earnshaw, Nick Clifton, Matthieu Longo

[-- Attachment #1: Type: text/plain, Size: 350 bytes --]


This patch introduces a new operand flag OPD_F_UNSIGNED to signal that
the immediate value should be treated as an unsigned value. The default
signedness of immediate operands is signed.
---
 opcodes/aarch64-opc.c | 90 ++++++++++++++++++++++++++++++++-----------
 opcodes/aarch64-opc.h |  7 ++++
 2 files changed, 74 insertions(+), 23 deletions(-)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: v0-0011-aarch64-add-flag-OPD_F_UNSIGNED-to-distinguish-si.patch --]
[-- Type: text/x-patch; name="v0-0011-aarch64-add-flag-OPD_F_UNSIGNED-to-distinguish-si.patch", Size: 4430 bytes --]

diff --git a/opcodes/aarch64-opc.c b/opcodes/aarch64-opc.c
index 5ac2277e102..ad5dfdc27b6 100644
--- a/opcodes/aarch64-opc.c
+++ b/opcodes/aarch64-opc.c
@@ -1614,6 +1614,53 @@ check_reglist (const aarch64_opnd_info *opnd,
   return true;
 }
 
+typedef struct
+{
+  int64_t min;
+  int64_t max;
+} imm_range_t;
+
+static imm_range_t
+imm_range_min_max(unsigned size, bool signed_rng)
+{
+  assert (size < 63);
+  imm_range_t r;
+  if (signed_rng)
+    {
+      r.max = (((int64_t) 0x1) << (size - 1)) - 1;
+      r.min = - r.max - 1;
+    }
+  else
+    {
+      r.max = (((int64_t) 0x1) << size) - 1;
+      r.min = 0;
+    }
+  return r;
+}
+
+/* Check that an immediate value is in the range provided by the operand type.  */
+static bool
+check_immediate_out_of_range(int64_t imm,
+			     enum aarch64_opnd type,
+			     aarch64_operand_error *mismatch_detail, int idx)
+{
+  const aarch64_operand *operand = get_operand_from_code (type);
+  uint8_t size = get_operand_fields_width (operand);
+  bool unsigned_imm = operand_need_unsigned_offset (operand);
+  bool (*value_fit_field) (int64_t, unsigned)
+    = (unsigned_imm
+      ? value_fit_unsigned_field_p
+      : value_fit_signed_field_p);
+
+  if (!value_fit_field (imm, size))
+    {
+      imm_range_t rng = imm_range_min_max (size, !unsigned_imm);
+      set_imm_out_of_range_error (mismatch_detail, idx, rng.min, rng.max);
+      return false;
+    }
+  return true;
+}
+
 /* Check that indexed ZA operand OPND has:
 
    - a selection register in the range [MIN_WREG, MIN_WREG + 3]
@@ -2339,27 +2386,25 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 	case AARCH64_OPND_ADDR_PCREL19:
 	case AARCH64_OPND_ADDR_PCREL21:
 	case AARCH64_OPND_ADDR_PCREL26:
-	  imm = opnd->imm.value;
-	  if (operand_need_shift_by_two (get_operand_from_code (type)))
-	    {
-	      /* The offset value in a PC-relative branch instruction is alway
-		 4-byte aligned and is encoded without the lowest 2 bits.  */
-	      if (!value_aligned_p (imm, 4))
-		{
-		  set_unaligned_error (mismatch_detail, idx, 4);
-		  return false;
-		}
-	      /* Right shift by 2 so that we can carry out the following check
-		 canonically.  */
-	      imm >>= 2;
-	    }
-	  size = get_operand_fields_width (get_operand_from_code (type));
-	  if (!value_fit_signed_field_p (imm, size))
-	    {
-	      set_other_error (mismatch_detail, idx,
-			       _("immediate out of range"));
+	  {
+	    imm = opnd->imm.value;
+	    if (operand_need_shift_by_two (get_operand_from_code (type)))
+	      {
+		/* The offset value in a PC-relative branch instruction is alway
+		   4-byte aligned and is encoded without the lowest 2 bits.  */
+		if (!value_aligned_p (imm, 4))
+		  {
+		    set_unaligned_error (mismatch_detail, idx, 4);
+		    return false;
+		  }
+		/* Right shift by 2 so that we can carry out the following check
+		   canonically.  */
+		imm >>= 2;
+	      }
+
+	    if (!check_immediate_out_of_range (imm, type, mismatch_detail, idx))
 	      return false;
-	    }
+	  }
 	  break;
 
 	case AARCH64_OPND_SME_ADDR_RI_U4xVL:
@@ -2773,9 +2818,8 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 	  assert (size < 32);
 	  if (!value_fit_signed_field_p (opnd->imm.value, size))
 	    {
-	      set_imm_out_of_range_error (mismatch_detail, idx,
-					  -(1 << (size - 1)),
-					  (1 << (size - 1)) - 1);
+	      imm_range_t rng = imm_range_min_max(size, true);
+	      set_imm_out_of_range_error (mismatch_detail, idx, rng.min, rng.max);
 	      return false;
 	    }
 	  break;
diff --git a/opcodes/aarch64-opc.h b/opcodes/aarch64-opc.h
index c4cb6003b4c..d02f17b6c7a 100644
--- a/opcodes/aarch64-opc.h
+++ b/opcodes/aarch64-opc.h
@@ -292,6 +292,7 @@ verify_constraints (const struct aarch64_inst *, const aarch64_insn, bfd_vma,
 #define OPD_F_SHIFT_BY_4	0x00000800	/* Need to left shift the field
 						   value by 4 to get the value
 						   of an immediate operand.  */
+#define OPD_F_UNSIGNED		0x00001000	/* Expect an unsigned value. */
 
 
 /* Register flags.  */
@@ -395,6 +396,12 @@ operand_need_shift_by_four (const aarch64_operand *operand)
   return (operand->flags & OPD_F_SHIFT_BY_4) != 0;
 }
 
+static inline bool
+operand_need_unsigned_offset (const aarch64_operand *operand)
+{
+  return (operand->flags & OPD_F_UNSIGNED) != 0;
+}
+
 static inline bool
 operand_maybe_stack_pointer (const aarch64_operand *operand)
 {

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH v0 12/13] aarch64: add PAuth_LR instructions with imm16 operand
  2024-07-08 12:34 [PATCH v0 00/13] aarch64: add instructions for Armv9.5-A PAC enhancement Matthieu Longo
                   ` (10 preceding siblings ...)
  2024-07-08 12:34 ` [PATCH v0 11/13] aarch64: add flag OPD_F_UNSIGNED to distinguish signedness of immediate operands Matthieu Longo
@ 2024-07-08 12:34 ` Matthieu Longo
  2024-07-08 12:34 ` [PATCH v0 13/13] aarch64: add DWARF CFI directive for PAuth_LR Matthieu Longo
  12 siblings, 0 replies; 14+ messages in thread
From: Matthieu Longo @ 2024-07-08 12:34 UTC (permalink / raw)
  To: binutils; +Cc: Richard Earnshaw, Nick Clifton, Matthieu Longo

[-- Attachment #1: Type: text/plain, Size: 1109 bytes --]


This patch adds the instructions required by Armv9.5-A PAC
enhancements.
- the imm16 variant of auti<k>sppc
- the imm16 variant of reta<k>sppc

It also adds:
- a new operand parser (ADDR_UPCREL16) for 16-bits unsigned
  immediate operand,
- a new relocation type (BFD_RELOC_AARCH64_AUTI_LO16_PCREL)
  specific to the auti<k>sppc and reta<k>sppc instructions
  and only used for computing the PC-relative offset, but
  does no relocation.
- the relevant tests for the instructions.
---
 bfd/elfnn-aarch64.c                      |  8 ++--
 bfd/reloc.c                              | 17 ++++++++-
 gas/config/tc-aarch64.c                  | 47 ++++++++++++++++++++++++
 gas/testsuite/gas/aarch64/pauth_lr-bad.l | 10 ++++-
 gas/testsuite/gas/aarch64/pauth_lr-bad.s | 15 ++++++++
 gas/testsuite/gas/aarch64/pauth_lr.d     | 15 +++++++-
 gas/testsuite/gas/aarch64/pauth_lr.s     | 17 +++++++++
 include/opcode/aarch64.h                 |  1 +
 opcodes/aarch64-opc.c                    | 28 +++++++++-----
 opcodes/aarch64-tbl.h                    | 12 ++++++
 10 files changed, 154 insertions(+), 16 deletions(-)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: v0-0012-aarch64-add-PAuth_LR-instructions-with-imm16-oper.patch --]
[-- Type: text/x-patch; name="v0-0012-aarch64-add-PAuth_LR-instructions-with-imm16-oper.patch", Size: 15712 bytes --]

diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c
index 000564672df..0c48e20f013 100644
--- a/bfd/elfnn-aarch64.c
+++ b/bfd/elfnn-aarch64.c
@@ -431,7 +431,7 @@ elfNN_aarch64_tlsdesc_small_plt_bti_entry[PLT_TLSDESC_ENTRY_SIZE] =
 
 /* Indexed by the bfd interal reloc enumerators.
    Therefore, the table needs to be synced with BFD_RELOC_AARCH64_*
-   in reloc.c.   */
+   in bfd/reloc.c, and with a RELOC_NUMBER in include/elf/aarch64.h */
 
 static reloc_howto_type elfNN_aarch64_howto_table[] =
 {
@@ -822,6 +822,8 @@ static reloc_howto_type elfNN_aarch64_howto_table[] =
 	 0xffff,		/* dst_mask */
 	 true),		/* pcrel_offset */
 
+  EMPTY_HOWTO (0), // BFD_RELOC_AARCH64_AUTI_LO16_PCREL
+
 /* Relocations to generate 19, 21 and 33 bit PC-relative load/store
    addresses: PG(x) is (x & ~0xfff).  */
 
@@ -8262,7 +8264,7 @@ elfNN_aarch64_maybe_function_sym (const asymbol *sym, asection *sec,
     return 0;
 
   size = (sym->flags & BSF_SYNTHETIC) ? 0 : elf_sym->internal_elf_sym.st_size;
-  
+
   if (!(sym->flags & BSF_SYNTHETIC))
     switch (ELF_ST_TYPE (elf_sym->internal_elf_sym.st_info))
       {
@@ -8280,7 +8282,7 @@ elfNN_aarch64_maybe_function_sym (const asymbol *sym, asection *sec,
 	default:
 	  return 0;
       }
-  
+
   if ((sym->flags & BSF_LOCAL)
       && bfd_is_aarch64_special_symbol_name (sym->name,
 					     BFD_AARCH64_SPECIAL_SYM_TYPE_ANY))
diff --git a/bfd/reloc.c b/bfd/reloc.c
index a187afe9b56..d9386a7fdc7 100644
--- a/bfd/reloc.c
+++ b/bfd/reloc.c
@@ -6776,6 +6776,7 @@ ENUMDOC
   This is a 64 bit reloc that stores the 32 bit offset value in two
   words (with an imm instruction).  The relocation is relative offset
   from start of TEXT.
+
 ENUM
   BFD_RELOC_KVX_RELOC_START
 ENUMDOC
@@ -6961,6 +6962,7 @@ ENUMDOC
   a few more enumerators after this one; those are mainly used by the
   KVX assembler for the internal fixup or to select one of the above
   enumerators.
+
 ENUM
   BFD_RELOC_AARCH64_RELOC_START
 ENUMDOC
@@ -6968,6 +6970,11 @@ ENUMDOC
   relocation enumerators.  N.B. the order of the enumerators is
   important as several tables in the AArch64 bfd backend are indexed
   by these enumerators; make sure they are all synced.
+  - bfd/elfnn-aarch64.c:elfNN_aarch64_howto_table
+    If the reloc is local and does not require bfd, fill in the gap
+    with EMPTY_HOWTO (0).
+  - include/elf/aarch64.h:RELOC_NUMBER
+    If the reloc does not depend on elf, you can skip this.
 ENUM
   BFD_RELOC_AARCH64_NULL
 ENUMDOC
@@ -7085,6 +7092,12 @@ ENUM
 ENUMDOC
   AArch64 MOVK instruction with most significant bits 47 to 63 of a
   signed value.
+ENUM
+  BFD_RELOC_AARCH64_AUTI_LO16_PCREL
+ENUMDOC
+  AArch64 AUTI<k>SPPC instructions, holding a 16 bit pc-relative word
+  offset.  The lowest two bits must be zero and are not stored in the
+  instruction, giving a 18 bit unsigned byte offset.
 ENUM
   BFD_RELOC_AARCH64_LD_LO19_PCREL
 ENUMDOC
@@ -7309,7 +7322,7 @@ ENUM
   BFD_RELOC_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC
 ENUMDOC
   Similar to BFD_RELOC_AARCH64_TLSLD_LDST32_DTPREL_LO12, but no
-  overflow check. 
+  overflow check.
 ENUM
   BFD_RELOC_AARCH64_TLSLD_LDST64_DTPREL_LO12
 ENUMDOC
@@ -7525,6 +7538,7 @@ ENUM
 ENUMDOC
   AArch64 pseudo relocation code to be used internally by the AArch64
   assembler and not (currently) written to any object files.
+
 ENUM
   BFD_RELOC_TILEPRO_COPY
 ENUMX
@@ -7685,6 +7699,7 @@ ENUMX
   BFD_RELOC_TILEPRO_IMM16_X1_TLS_LE_HA
 ENUMDOC
   Tilera TILEPro Relocations.
+
 ENUM
   BFD_RELOC_TILEGX_HW0
 ENUMX
diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c
index f69b0b0c0e2..9115e20a186 100644
--- a/gas/config/tc-aarch64.c
+++ b/gas/config/tc-aarch64.c
@@ -5123,6 +5123,12 @@ encode_addsub_imm_shift_amount (uint32_t cnt)
   return cnt << 22;
 }
 
+/* encode the imm16 field of RETA<k>SPPC instruction */
+static inline uint32_t
+encode_pauthauti_imm16(uint32_t imm)
+{
+  return imm << 5;
+}
 
 /* encode the imm field of Adr instruction */
 static inline uint32_t
@@ -7413,6 +7419,7 @@ parse_operands (char *str, const aarch64_opcode *opcode)
 	  break;
 
 	case AARCH64_OPND_ADDR_PCREL14:
+	case AARCH64_OPND_ADDR_UPCREL16:
 	case AARCH64_OPND_ADDR_PCREL19:
 	case AARCH64_OPND_ADDR_PCREL21:
 	case AARCH64_OPND_ADDR_PCREL26:
@@ -7464,6 +7471,11 @@ parse_operands (char *str, const aarch64_opcode *opcode)
 		      (opcode->op == OP_BL) ? BFD_RELOC_AARCH64_CALL26
 			 : BFD_RELOC_AARCH64_JUMP26;
 		    break;
+		  case ic_pauth_lr:
+		    /* e.g. AUTI<k>SPPC or RETA<k>SPPC  */
+		    gas_assert (operands[i] == AARCH64_OPND_ADDR_UPCREL16);
+		    inst.reloc.type = BFD_RELOC_AARCH64_AUTI_LO16_PCREL;
+		    break;
 		  case loadlit:
 		    gas_assert (operands[i] == AARCH64_OPND_ADDR_PCREL19);
 		    inst.reloc.type = BFD_RELOC_AARCH64_LD_LO19_PCREL;
@@ -9639,6 +9651,41 @@ md_apply_fix (fixS * fixP, valueT * valP, segT seg)
 	}
       break;
 
+    case BFD_RELOC_AARCH64_AUTI_LO16_PCREL:
+      if (fixP->fx_done)
+	{
+	  // FIXME: I don't think this inversion should be done here. There
+	  // should be a better generic mechanism to handle unsigned relative
+	  // offsets. However, I am not sure yet where to add it, and the
+	  // complexity of the change.
+	  unsigned long value_ = (unsigned long) -value;
+	  if (value > 0)
+	    as_bad_where (fixP->fx_file, fixP->fx_line,
+			  _("negative pc-relative address offset not allowed"\
+			    " in this context: %ld"), -value);
+	  else if (unsigned_overflow(value_, 18))
+	    as_bad_where (fixP->fx_file, fixP->fx_line,
+			  _("pc-relative address offset out of range: %#lx"), value_);
+	  if (value_ & 3)
+	    as_bad_where (fixP->fx_file, fixP->fx_line,
+			  _("pc-relative address offset not word aligned"));
+	  insn = get_aarch64_insn (buf);
+	  insn |= encode_pauthauti_imm16 (value_ >> 2);
+	  put_aarch64_insn (buf, insn);
+	}
+      else
+	{
+	  // The symbold is probably external or undeclared. This is unsupported
+	  // for this relocation type which is only used for computing the
+	  // PC-relative offset, but does no relocation.
+	  gas_assert (fixP->fx_addsy && !S_IS_DEFINED (fixP->fx_addsy));
+	  as_bad_where (fixP->fx_file, fixP->fx_line,
+			_("undefined symbol %s used as an immediate value"),
+			S_GET_NAME (fixP->fx_addsy));
+	  goto apply_fix_return;
+	}
+      break;
+
     case BFD_RELOC_AARCH64_ADR_LO21_PCREL:
       if (fixP->fx_done || !seg->use_rela_p)
 	{
diff --git a/gas/testsuite/gas/aarch64/pauth_lr-bad.l b/gas/testsuite/gas/aarch64/pauth_lr-bad.l
index d0a629f216f..184e3f8398f 100644
--- a/gas/testsuite/gas/aarch64/pauth_lr-bad.l
+++ b/gas/testsuite/gas/aarch64/pauth_lr-bad.l
@@ -8,4 +8,12 @@
 .*: Info:    did you mean this\?
 .*: Info:    	retaasppcr x0
 .*: Error: unexpected register type at operand 1 -- `retaasppcr sp'
-.*: Error: unexpected register type at operand 1 -- `retaasppcr xzr'
\ No newline at end of file
+.*: Error: unexpected register type at operand 1 -- `retaasppcr xzr'
+.*: Error: immediate value must be a multiple of 4 at operand 1 -- `retaasppc 0xff'
+.*: Error: immediate value must be a multiple of 4 at operand 1 -- `retaasppc 0x3fffd'
+.*: Error: immediate value out of range 0 to 65535 at operand 1 -- `retaasppc 0x4fffc'
+.*: Error: immediate value out of range 0 to 65535 at operand 1 -- `retaasppc -0x4'
+.*: Error: negative pc-relative address offset not allowed in this context: -12
+.*: Error: undefined symbol external_symbol used as an immediate value
+.*: Error: pc-relative address offset out of range: 0x40000
+.*: Error: negative pc-relative address offset not allowed in this context: -12
diff --git a/gas/testsuite/gas/aarch64/pauth_lr-bad.s b/gas/testsuite/gas/aarch64/pauth_lr-bad.s
index 98840d4c257..32f5c4b65cf 100644
--- a/gas/testsuite/gas/aarch64/pauth_lr-bad.s
+++ b/gas/testsuite/gas/aarch64/pauth_lr-bad.s
@@ -10,3 +10,18 @@ lr_signing:
 	retaasppcr w0 // 32-bit registers not allowed
 	retaasppcr sp // SP not allowed
 	retaasppcr xzr // zero register not allowed
+
+	// Invalid values
+	retaasppc 0xff // not multiple of 4
+	retaasppc 0x3fffd // max value overflowed but might not be detected due to bit shift
+	retaasppc 0x4fffc // aligned overflow: not possible to represent the value on 16 bits
+
+	retaasppc -0x4  // unsupported negative offset
+	retaasppc .+0xc // it should be impossible to jump before .text [NOK. FIXME: . notation seems to be taken into account as expected]
+	retaasppc external_symbol
+
+	.balign 0x40000 // NOP filling
+
+	retaasppc lr_signing // the distance between the label and the reta<k>sppc instruction
+			     // is above the limit that can be encoded (=0x3fffc).
+	retaasppc .+0xc // current PC + offset is above the limit that can be encoded. [NOK. FIXME: . notation seems to be taken into account as expected]
diff --git a/gas/testsuite/gas/aarch64/pauth_lr.d b/gas/testsuite/gas/aarch64/pauth_lr.d
index ddd65b77fd1..ab5700897dc 100644
--- a/gas/testsuite/gas/aarch64/pauth_lr.d
+++ b/gas/testsuite/gas/aarch64/pauth_lr.d
@@ -21,4 +21,17 @@ Disassembly of section \.text:
 .*:	dac1941e 	autibsppcr	x0
 .*:	d65f0be0 	retaasppcr	x0
 .*:	d65f0bfe 	retaasppcr	x30
-.*:	d65f0fe0 	retabsppcr	x0
\ No newline at end of file
+.*:	d65f0fe0 	retabsppcr	x0
+[^\s]+\s<lr_signing>:
+      3c:	f380001f 	autiasppc	3c <lr_signing>
+      40:	f3a0003f 	autibsppc	3c <lr_signing>
+      44:	5500005f 	retaasppc	3c <lr_signing>
+      48:	5520007f 	retabsppc	3c <lr_signing>
+      4c:	5500001f 	retaasppc	4c <lr_signing\+0x10>
+      50:	5500001f 	retaasppc	50 <lr_signing\+0x14>
+      54:	5500003f 	retaasppc	50 <lr_signing\+0x14>
+      58:	5500011f 	retaasppc	38 <lr_signing-0x4>
+      5c:	550002df 	retaasppc	4 <lr_signing-0x38>
+#...
+   40000:	55091a7f 	retaasppc	2dcb4 <lr_signing\+0x2dc78>
+   40004:	551fffff 	retaasppc	8 <lr_signing-0x34>
diff --git a/gas/testsuite/gas/aarch64/pauth_lr.s b/gas/testsuite/gas/aarch64/pauth_lr.s
index cdedd6e4588..3f57559d3df 100644
--- a/gas/testsuite/gas/aarch64/pauth_lr.s
+++ b/gas/testsuite/gas/aarch64/pauth_lr.s
@@ -28,3 +28,20 @@
 	retaasppcr x0
 	retaasppcr x30
 	retabsppcr x0
+
+lr_signing:
+	autiasppc lr_signing
+	autibsppc lr_signing
+	retaasppc lr_signing
+	retabsppc lr_signing
+
+	retaasppc 0x0 // min: reference to itself
+	retaasppc .+0x0 // min: current PC + 0
+	retaasppc 0x4 // first valid value after min: point to previous instruction
+	retaasppc 0x20
+        retaasppc .-0x58 // point to pacm
+
+	.balign 0x40000 // NOP filling
+
+	retaasppc 0x1234c // a random value in the valid range
+	retaasppc 0x3fffc // max
diff --git a/include/opcode/aarch64.h b/include/opcode/aarch64.h
index 81c9b1f1220..4661dc83e17 100644
--- a/include/opcode/aarch64.h
+++ b/include/opcode/aarch64.h
@@ -639,6 +639,7 @@ enum aarch64_opnd
 
   AARCH64_OPND_ADDR_ADRP,	/* Memory address for ADRP */
   AARCH64_OPND_ADDR_PCREL14,	/* 14-bit PC-relative address for e.g. TBZ.  */
+  AARCH64_OPND_ADDR_UPCREL16,	/* unsigned 16-bit PC-relative offset (imm16:'00') for e.g. RETA<k>... */
   AARCH64_OPND_ADDR_PCREL19,	/* 19-bit PC-relative address for e.g. LDR.  */
   AARCH64_OPND_ADDR_PCREL21,	/* 21-bit PC-relative address for e.g. ADR.  */
   AARCH64_OPND_ADDR_PCREL26,	/* 26-bit PC-relative address for e.g. BL.  */
diff --git a/opcodes/aarch64-opc.c b/opcodes/aarch64-opc.c
index ad5dfdc27b6..9848e15392a 100644
--- a/opcodes/aarch64-opc.c
+++ b/opcodes/aarch64-opc.c
@@ -2383,6 +2383,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 	  break;
 
 	case AARCH64_OPND_ADDR_PCREL14:
+	case AARCH64_OPND_ADDR_UPCREL16:
 	case AARCH64_OPND_ADDR_PCREL19:
 	case AARCH64_OPND_ADDR_PCREL21:
 	case AARCH64_OPND_ADDR_PCREL26:
@@ -4730,19 +4731,26 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
       break;
 
     case AARCH64_OPND_ADDR_PCREL14:
+    case AARCH64_OPND_ADDR_UPCREL16:
     case AARCH64_OPND_ADDR_PCREL19:
     case AARCH64_OPND_ADDR_PCREL21:
     case AARCH64_OPND_ADDR_PCREL26:
-      addr = pc + AARCH64_PCREL_OFFSET + opnd->imm.value;
-      if (pcrel_p)
-	*pcrel_p = 1;
-      if (address)
-	*address = addr;
-      /* This is not necessary during the disassembling, as print_address_func
-	 in the disassemble_info will take care of the printing.  But some
-	 other callers may be still interested in getting the string in *STR,
-	 so here we do snprintf regardless.  */
-      snprintf (buf, size, "%s", style_addr (styler, "#0x%" PRIx64, addr));
+      {
+	const aarch64_operand *operand = get_operand_from_code (opnd->type);
+	if (operand_need_unsigned_offset (operand))
+	  addr = pc + AARCH64_PCREL_OFFSET - opnd->imm.value;
+	else
+	  addr = pc + AARCH64_PCREL_OFFSET + opnd->imm.value;
+	if (pcrel_p)
+	  *pcrel_p = 1;
+	if (address)
+	  *address = addr;
+	/* This is not necessary during the disassembling, as print_address_func
+	   in the disassemble_info will take care of the printing.  But some
+	   other callers may be still interested in getting the string in *STR,
+	   so here we do snprintf regardless.  */
+	snprintf (buf, size, "%s", style_addr (styler, "#0x%" PRIx64, addr));
+      }
       break;
 
     case AARCH64_OPND_ADDR_SIMPLE:
diff --git a/opcodes/aarch64-tbl.h b/opcodes/aarch64-tbl.h
index ef7b69e4970..58d294b0d33 100644
--- a/opcodes/aarch64-tbl.h
+++ b/opcodes/aarch64-tbl.h
@@ -1034,6 +1034,12 @@
   QLF4(V_16B, V_16B, V_16B, imm_0_15),	\
 }
 
+/* e.g. AUTI<k>SPPC <label_imm16:00>  */
+#define QL_PAUTH_IMM16		\
+{				\
+  QLF1(imm_0_15),		\
+}
+
 /* e.g. AUTI<k>SPPCR Xn  */
 #define QL_PAUTH_REG		\
 {				\
@@ -3896,6 +3902,8 @@ const struct aarch64_opcode aarch64_opcode_table[] =
   PAUTH_INSN ("eretab", 0xd69f0fff, 0xffffffff, branch_reg, OP0 (), {}, 0),
   PAUTH_LR_INSN ("retaasppcr", 0xd65f0be0, 0xffffffe0, ic_pauth_lr, OP1 (Rd), QL_PAUTH_REG, 0),
   PAUTH_LR_INSN ("retabsppcr", 0xd65f0fe0, 0xffffffe0, ic_pauth_lr, OP1 (Rd), QL_PAUTH_REG, 0),
+  PAUTH_LR_INSN ("retaasppc", 0x5500001f, 0xffe0001f, ic_pauth_lr, OP1 (ADDR_UPCREL16), QL_PAUTH_IMM16, 0),
+  PAUTH_LR_INSN ("retabsppc", 0x5520001f, 0xffe0001f, ic_pauth_lr, OP1 (ADDR_UPCREL16), QL_PAUTH_IMM16, 0),
   /* Compare & branch (immediate).  */
   CORE_INSN ("cbz", 0x34000000, 0x7f000000, compbranch, 0, OP2 (Rt, ADDR_PCREL19), QL_R_PCREL, F_SF),
   CORE_INSN ("cbnz", 0x35000000, 0x7f000000, compbranch, 0, OP2 (Rt, ADDR_PCREL19), QL_R_PCREL, F_SF),
@@ -3959,6 +3967,8 @@ const struct aarch64_opcode aarch64_opcode_table[] =
   PAUTH_INSN ("autdb", 0xdac11c00, 0xfffffc00, dp_1src, OP2 (Rd, Rn_SP), QL_I2SAMEX, 0),
   PAUTH_LR_INSN ("autiasppcr", 0xdac1901e, 0xfffffc1f, ic_pauth_lr, OP1 (Rn), QL_PAUTH_REG, 0),
   PAUTH_LR_INSN ("autibsppcr", 0xdac1941e, 0xfffffc1f, ic_pauth_lr, OP1 (Rn), QL_PAUTH_REG, 0),
+  PAUTH_LR_INSN ("autiasppc", 0xf380001f, 0xffe0001f, ic_pauth_lr, OP1 (ADDR_UPCREL16), QL_PAUTH_IMM16, 0),
+  PAUTH_LR_INSN ("autibsppc", 0xf3a0001f, 0xffe0001f, ic_pauth_lr, OP1 (ADDR_UPCREL16), QL_PAUTH_IMM16, 0),
   PAUTH_LR_INSN ("autia171615", 0xdac1bbfe, 0xffffffff, ic_system, OP0 (), {}, 0),
   PAUTH_LR_INSN ("autib171615", 0xdac1bffe, 0xffffffff, ic_system, OP0 (), {}, 0),
   PAUTH_INSN ("paciza", 0xdac123e0, 0xffffffe0, dp_1src, OP1 (Rd), QL_I1X, 0),
@@ -7003,6 +7013,8 @@ const struct aarch64_opcode aarch64_opcode_table[] =
       "21-bit PC-relative address of a 4KB page")			\
     Y(ADDRESS, imm, "ADDR_PCREL14", OPD_F_SEXT | OPD_F_SHIFT_BY_2,	\
       F(FLD_imm14), "14-bit PC-relative address")			\
+    Y(ADDRESS, imm, "ADDR_UPCREL16", OPD_F_SHIFT_BY_2 | OPD_F_UNSIGNED,	\
+      F(FLD_imm16_5), "unsigned 16-bit PC-relative offset (imm16:'00')")\
     Y(ADDRESS, imm, "ADDR_PCREL19", OPD_F_SEXT | OPD_F_SHIFT_BY_2,	\
       F(FLD_imm19), "19-bit PC-relative address")			\
     Y(ADDRESS, imm, "ADDR_PCREL21", OPD_F_SEXT, F(FLD_immhi,FLD_immlo),	\

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH v0 13/13] aarch64: add DWARF CFI directive for PAuth_LR
  2024-07-08 12:34 [PATCH v0 00/13] aarch64: add instructions for Armv9.5-A PAC enhancement Matthieu Longo
                   ` (11 preceding siblings ...)
  2024-07-08 12:34 ` [PATCH v0 12/13] aarch64: add PAuth_LR instructions with imm16 operand Matthieu Longo
@ 2024-07-08 12:34 ` Matthieu Longo
  12 siblings, 0 replies; 14+ messages in thread
From: Matthieu Longo @ 2024-07-08 12:34 UTC (permalink / raw)
  To: binutils; +Cc: Richard Earnshaw, Nick Clifton, Matthieu Longo

[-- Attachment #1: Type: text/plain, Size: 1305 bytes --]


This patch adds a new CFI directive (cfi_negate_ra_state_with_pc) which
set an additional bit in the RA state to inform that RA was signed with
SP but also PC as an additional diversifier.

RA state | Description
0b00     | Return address not signed (default if no cfi_negate_ra_state*)
0b01     | Return address signed with SP (cfi_negate_ra_state)
0b10     | Invalid state
0b11     | Return address signed with SP+PC (cfi_negate_ra_state_with_pc)

It also adds the relevant tests for the new cfi directive.
---
 bfd/elf-eh-frame.c                            |  1 +
 binutils/dwarf.c                              |  5 ++
 gas/dw2gencfi.c                               | 10 +++
 gas/gen-sframe.c                              | 25 +++++++-
 gas/gen-sframe.h                              |  5 +-
 gas/scfidw2gen.c                              |  1 +
 .../gas/aarch64/pac_negate_ra_state_with_pc.d | 64 +++++++++++++++++++
 .../gas/aarch64/pac_negate_ra_state_with_pc.s | 53 +++++++++++++++
 include/dwarf2.def                            |  4 +-
 include/sframe.h                              |  2 +-
 10 files changed, 165 insertions(+), 5 deletions(-)
 create mode 100644 gas/testsuite/gas/aarch64/pac_negate_ra_state_with_pc.d
 create mode 100644 gas/testsuite/gas/aarch64/pac_negate_ra_state_with_pc.s


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: v0-0013-aarch64-add-DWARF-CFI-directive-for-PAuth_LR.patch --]
[-- Type: text/x-patch; name="v0-0013-aarch64-add-DWARF-CFI-directive-for-PAuth_LR.patch", Size: 10138 bytes --]

diff --git a/bfd/elf-eh-frame.c b/bfd/elf-eh-frame.c
index 902d7c16334..acee87f2a5b 100644
--- a/bfd/elf-eh-frame.c
+++ b/bfd/elf-eh-frame.c
@@ -359,6 +359,7 @@ skip_cfa_op (bfd_byte **iter, bfd_byte *end, unsigned int encoded_ptr_width)
     case DW_CFA_remember_state:
     case DW_CFA_restore_state:
     case DW_CFA_GNU_window_save:
+    case DW_CFA_AARCH64_negate_ra_state_with_pc:
       /* No arguments.  */
       return true;
 
diff --git a/binutils/dwarf.c b/binutils/dwarf.c
index 972bb920161..7e4a4427095 100644
--- a/binutils/dwarf.c
+++ b/binutils/dwarf.c
@@ -10358,6 +10358,11 @@ display_debug_frames (struct dwarf_section *section,
 	      fc->pc_begin += ofs;
 	      break;
 
+	    case DW_CFA_AARCH64_negate_ra_state_with_pc:
+	      if (! do_debug_frames_interp)
+		printf ("  DW_CFA_AARCH64_negate_ra_state_with_pc\n");
+	      break;
+
 	    case DW_CFA_GNU_window_save:
 	      if (! do_debug_frames_interp)
 		printf ("  %s\n", DW_CFA_GNU_window_save_name[is_aarch64]);
diff --git a/gas/dw2gencfi.c b/gas/dw2gencfi.c
index db0261dd187..936cf7eb4b0 100644
--- a/gas/dw2gencfi.c
+++ b/gas/dw2gencfi.c
@@ -718,6 +718,7 @@ const pseudo_typeS cfi_pseudo_table[] =
     { "cfi_restore_state", dot_cfi, DW_CFA_restore_state },
     { "cfi_window_save", dot_cfi, DW_CFA_GNU_window_save },
     { "cfi_negate_ra_state", dot_cfi, DW_CFA_AARCH64_negate_ra_state },
+    { "cfi_negate_ra_state_with_pc", dot_cfi, DW_CFA_AARCH64_negate_ra_state_with_pc },
     { "cfi_escape", dot_cfi_escape, 0 },
     { "cfi_signal_frame", dot_cfi, CFI_signal_frame },
     { "cfi_personality", dot_cfi_personality, 0 },
@@ -918,6 +919,10 @@ dot_cfi (int arg)
       cfi_add_CFA_insn (DW_CFA_GNU_window_save);
       break;
 
+    case DW_CFA_AARCH64_negate_ra_state_with_pc:
+      cfi_add_CFA_insn (DW_CFA_AARCH64_negate_ra_state_with_pc);
+      break;
+
     case CFI_signal_frame:
       frchain_now->frch_cfi_data->cur_fde_data->signal_frame = 1;
       break;
@@ -1758,6 +1763,10 @@ output_cfi_insn (struct cfi_insn_data *insn)
       out_one (DW_CFA_GNU_window_save);
       break;
 
+    case DW_CFA_AARCH64_negate_ra_state_with_pc:
+      out_one (DW_CFA_AARCH64_negate_ra_state_with_pc);
+      break;
+
     case CFI_escape:
       {
 	struct cfi_escape_data *e;
@@ -2216,6 +2225,7 @@ cfi_change_reg_numbers (struct cfi_insn_data *insn, segT ccseg)
 	case DW_CFA_remember_state:
 	case DW_CFA_restore_state:
 	case DW_CFA_GNU_window_save:
+	case DW_CFA_AARCH64_negate_ra_state_with_pc:
 	case CFI_escape:
 	case CFI_label:
 	  break;
diff --git a/gas/gen-sframe.c b/gas/gen-sframe.c
index 247b65a37d0..77870dde166 100644
--- a/gas/gen-sframe.c
+++ b/gas/gen-sframe.c
@@ -928,7 +928,7 @@ sframe_row_entry_initialize (struct sframe_row_entry *cur_fre,
   cur_fre->ra_loc = prev_fre->ra_loc;
   cur_fre->ra_offset = prev_fre->ra_offset;
   /* Treat RA mangling as a sticky bit.  It retains its value until another
-     .cfi_negate_ra_state is seen.  */
+     .cfi_negate_ra_state or .cfi_negate_ra_state_with_pc is seen.  */
   cur_fre->ra_signing_info = prev_fre->ra_signing_info;
 }
 
@@ -1306,6 +1306,26 @@ sframe_xlate_do_gnu_window_save (struct sframe_xlate_ctx *xlate_ctx,
   return SFRAME_XLATE_ERR_NOTREPRESENTED;  /* Not represented.  */
 }
 
+/* Translate DW_CFA_AARCH64_negate_ra_state_with_pc into SFrame context.
+   Return SFRAME_XLATE_OK if success.  */
+
+static int
+sframe_xlate_do_aarch64_negate_ra_state_with_pc (struct sframe_xlate_ctx *xlate_ctx,
+						 struct cfi_insn_data *cfi_insn ATTRIBUTE_UNUSED)
+{
+  struct sframe_row_entry *cur_fre = xlate_ctx->cur_fre;
+
+  gas_assert (cur_fre);
+  /* Toggle the mangled RA status bit.  */
+  cur_fre->ra_signing_info
+    = ((cur_fre->ra_signing_info == RA_no_signing)
+       ? RA_signing_SP_PC
+       : RA_no_signing);
+  cur_fre->merge_candidate = false;
+
+  return SFRAME_XLATE_OK;
+}
+
 /* Returns the DWARF call frame instruction name or fake CFI name for the
    specified CFI opcode, or NULL if the value is not recognized.  */
 
@@ -1396,6 +1416,9 @@ sframe_do_cfi_insn (struct sframe_xlate_ctx *xlate_ctx,
     case DW_CFA_GNU_window_save:
       err = sframe_xlate_do_gnu_window_save (xlate_ctx, cfi_insn);
       break;
+    case DW_CFA_AARCH64_negate_ra_state_with_pc:
+      err = sframe_xlate_do_aarch64_negate_ra_state_with_pc (xlate_ctx, cfi_insn);
+      break;
     case DW_CFA_register:
       err = sframe_xlate_do_register (xlate_ctx, cfi_insn);
       break;
diff --git a/gas/gen-sframe.h b/gas/gen-sframe.h
index db1e5de968f..81c99bfc263 100644
--- a/gas/gen-sframe.h
+++ b/gas/gen-sframe.h
@@ -43,8 +43,9 @@
 
 typedef enum ATTRIBUTE_PACKED
 {
-  RA_no_signing = 0x0,
-  RA_signing_SP = 0x1,
+  RA_no_signing    = 0x0,
+  RA_signing_SP    = 0x1,
+  RA_signing_SP_PC = 0x3,
 } RA_signing_method_t;
 
 struct sframe_row_entry
diff --git a/gas/scfidw2gen.c b/gas/scfidw2gen.c
index 2b018fac8bd..1fd0cd832e5 100644
--- a/gas/scfidw2gen.c
+++ b/gas/scfidw2gen.c
@@ -113,6 +113,7 @@ const pseudo_typeS scfi_pseudo_table[] =
     { "cfi_restore_state", dot_scfi_ignore, 0 },
     { "cfi_window_save", dot_scfi_ignore, 0 },
     { "cfi_negate_ra_state", dot_scfi_ignore, 0 },
+    { "cfi_negate_ra_state_with_pc", dot_scfi_ignore, 0 },
     { "cfi_escape", dot_scfi_ignore, 0 },
     { "cfi_personality", dot_scfi_ignore, 0 },
     { "cfi_personality_id", dot_scfi_ignore, 0 },
diff --git a/gas/testsuite/gas/aarch64/pac_negate_ra_state_with_pc.d b/gas/testsuite/gas/aarch64/pac_negate_ra_state_with_pc.d
new file mode 100644
index 00000000000..e3ffc9eb494
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/pac_negate_ra_state_with_pc.d
@@ -0,0 +1,64 @@
+#source: pac_negate_ra_state_with_pc.s
+#as: -march=armv9.4-a+pauth-lr
+#objdump: --dwarf=frames
+# This test is only valid on ELF based ports.
+#notarget: *-*-*coff *-*-pe *-*-wince *-*-*aout* *-*-netbsd
+
+.+:     file .+
+
+Contents of the .eh_frame section:
+
+
+00000000 0000000000000010 00000000 CIE
+  Version:               1
+  Augmentation:          "zR"
+  Code alignment factor: 4
+  Data alignment factor: -8
+  Return address column: 30
+  Augmentation data:     1b
+  DW_CFA_def_cfa: r31 \(sp\) ofs 0
+
+00000014 000000000000001c 00000018 FDE cie=00000000 pc=0000000000000000..0000000000000014
+  DW_CFA_advance_loc: 4 to 0000000000000004
+  DW_CFA_AARCH64_negate_ra_state_with_pc
+  DW_CFA_advance_loc: 4 to 0000000000000008
+  DW_CFA_def_cfa_offset: 16
+  DW_CFA_offset: r29 \(x29\) at cfa-16
+  DW_CFA_offset: r30 \(x30\) at cfa-8
+  DW_CFA_advance_loc: 8 to 0000000000000010
+  DW_CFA_restore: r30 \(x30\)
+  DW_CFA_restore: r29 \(x29\)
+  DW_CFA_advance_loc: 4 to 0000000000000014
+  DW_CFA_AARCH64_negate_ra_state_with_pc
+  DW_CFA_nop
+
+00000034 0000000000000014 00000000 CIE
+  Version:               1
+  Augmentation:          "zRB"
+  Code alignment factor: 4
+  Data alignment factor: -8
+  Return address column: 30
+  Augmentation data:     1b
+  DW_CFA_def_cfa: r31 \(sp\) ofs 0
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+
+0000004c 0000000000000020 0000001c FDE cie=00000034 pc=0000000000000014..0000000000000038
+  DW_CFA_advance_loc: 8 to 000000000000001c
+  DW_CFA_AARCH64_negate_ra_state_with_pc
+  DW_CFA_advance_loc: 4 to 0000000000000020
+  DW_CFA_def_cfa_offset: 16
+  DW_CFA_offset: r29 \(x29\) at cfa-16
+  DW_CFA_offset: r30 \(x30\) at cfa-8
+  DW_CFA_advance_loc: 8 to 0000000000000028
+  DW_CFA_restore: r30 \(x30\)
+  DW_CFA_restore: r29 \(x29\)
+  DW_CFA_advance_loc: 12 to 0000000000000034
+  DW_CFA_AARCH64_negate_ra_state_with_pc
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+
diff --git a/gas/testsuite/gas/aarch64/pac_negate_ra_state_with_pc.s b/gas/testsuite/gas/aarch64/pac_negate_ra_state_with_pc.s
new file mode 100644
index 00000000000..e179b40ab1a
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/pac_negate_ra_state_with_pc.s
@@ -0,0 +1,53 @@
+	.text
+	.align	2
+	.global	_Z5foo_pauth_lrv
+	.type	_Z5foo_pauth_lrv, %function
+_Z5foo_pauth_lrv:
+.LFB0:
+	.cfi_startproc
+	paciasppc
+	.cfi_negate_ra_state_with_pc
+	stp		x29, x30, [sp, -16]!
+	.cfi_def_cfa_offset 16
+	.cfi_offset 29, -16
+	.cfi_offset 30, -8
+	mov		x29, sp
+	// ...
+	ldp		x29, x30, [sp], #16
+	.cfi_restore 30
+	.cfi_restore 29
+	retaasppc	.LFB0
+	.cfi_negate_ra_state_with_pc
+	.cfi_endproc
+.LFE0:
+	.size	_Z5foo_pauth_lrv, .-_Z5foo_pauth_lrv
+
+
+	.align	2
+	.global	_Z5foo_pacmv
+	.type	_Z5foo_pacmv, %function
+_Z5foo_pac2_compatible_pauthv:
+.LFB1:
+	.cfi_startproc
+	.cfi_b_key_frame
+	hint		#0x27 // pacm
+.Ltmp1:
+	hint		#0x1b // pacibsp
+	.cfi_negate_ra_state_with_pc
+	stp		x29, x30, [sp, -16]!
+	.cfi_def_cfa_offset 16
+	.cfi_offset 29, -16
+	.cfi_offset 30, -8
+	mov		x29, sp
+	// ...
+	ldp		x29, x30, [sp], #16
+	.cfi_restore 30
+	.cfi_restore 29
+	adr		x16, .Ltmp1
+	hint		#0x27 // pacm
+	hint		#0x1f // autibsp
+	.cfi_negate_ra_state_with_pc
+	ret
+	.cfi_endproc
+.LFE1:
+	.size	_Z5foo_pac2_compatible_pauthv, .-_Z5foo_pac2_compatible_pauthv
diff --git a/include/dwarf2.def b/include/dwarf2.def
index 66c7fa1220f..95601fc7018 100644
--- a/include/dwarf2.def
+++ b/include/dwarf2.def
@@ -788,9 +788,11 @@ DW_CFA (DW_CFA_MIPS_advance_loc8, 0x1d)
 /* GNU extensions.
    NOTE: DW_CFA_GNU_window_save is multiplexed on Sparc and AArch64.  */
 DW_CFA (DW_CFA_GNU_window_save, 0x2d)
-DW_CFA_DUP (DW_CFA_AARCH64_negate_ra_state, 0x2d)
 DW_CFA (DW_CFA_GNU_args_size, 0x2e)
 DW_CFA (DW_CFA_GNU_negative_offset_extended, 0x2f)
+/* AArch64 extensions. */
+DW_CFA (DW_CFA_AARCH64_negate_ra_state_with_pc, 0x2c)
+DW_CFA_DUP (DW_CFA_AARCH64_negate_ra_state, 0x2d)
 
 DW_END_CFA
 
diff --git a/include/sframe.h b/include/sframe.h
index 53388aaaa91..f7a830a7275 100644
--- a/include/sframe.h
+++ b/include/sframe.h
@@ -265,7 +265,7 @@ typedef struct sframe_fre_info
 
 /* Set the mangled_ra_p bit as indicated.  */
 #define SFRAME_V1_FRE_INFO_UPDATE_RA_SIGNING_INFO(ra_signing_info, fre_info) \
-  ((((ra_signing_info) & 0x1) << 7) | ((fre_info) & 0x7f))
+  ((((ra_signing_info) & 0x3) << 7) | ((fre_info) & 0x7f))
 
 #define SFRAME_V1_FRE_CFA_BASE_REG_ID(data)	  ((data) & 0x1)
 #define SFRAME_V1_FRE_OFFSET_COUNT(data)	  (((data) >> 1) & 0xf)

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2024-07-08 12:36 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-07-08 12:34 [PATCH v0 00/13] aarch64: add instructions for Armv9.5-A PAC enhancement Matthieu Longo
2024-07-08 12:34 ` [PATCH v0 01/13] aarch64: make comment clearer about the location Matthieu Longo
2024-07-08 12:34 ` [PATCH v0 02/13] aarch64: constify unchanged char* arguments Matthieu Longo
2024-07-08 12:34 ` [PATCH v0 03/13] aarch64: change returned type to bool to match semantic of functions Matthieu Longo
2024-07-08 12:34 ` [PATCH v0 04/13] aarch64: improve debuggability on array of enum Matthieu Longo
2024-07-08 12:34 ` [PATCH v0 05/13] aarch64: remove redundant register type R_N Matthieu Longo
2024-07-08 12:34 ` [PATCH v0 06/13] aarch64: testsuite: remove hard-coded instruction addresses Matthieu Longo
2024-07-08 12:34 ` [PATCH v0 07/13] aarch64: refactor binary approach for RA signing method to make it extendable Matthieu Longo
2024-07-08 12:34 ` [PATCH v0 08/13] aarch64: add PAuth_LR instructions belonging to NOP space Matthieu Longo
2024-07-08 12:34 ` [PATCH v0 09/13] aarch64: add pauth-lr feature option for Armv9.5-A PAC enhancements Matthieu Longo
2024-07-08 12:34 ` [PATCH v0 10/13] aarch64: add PAuth_LR instructions with no or one-register operand Matthieu Longo
2024-07-08 12:34 ` [PATCH v0 11/13] aarch64: add flag OPD_F_UNSIGNED to distinguish signedness of immediate operands Matthieu Longo
2024-07-08 12:34 ` [PATCH v0 12/13] aarch64: add PAuth_LR instructions with imm16 operand Matthieu Longo
2024-07-08 12:34 ` [PATCH v0 13/13] aarch64: add DWARF CFI directive for PAuth_LR Matthieu Longo

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).