1cefc9
diff -rup binutils.orig/bfd/elfnn-aarch64.c binutils-2.30/bfd/elfnn-aarch64.c
1cefc9
--- binutils.orig/bfd/elfnn-aarch64.c	2020-11-04 14:53:52.144476367 +0000
1cefc9
+++ binutils-2.30/bfd/elfnn-aarch64.c	2020-11-04 14:56:42.275422499 +0000
1cefc9
@@ -2191,6 +2191,9 @@ struct elf_aarch64_obj_tdata
1cefc9
 
1cefc9
   /* Zero to warn when linking objects with incompatible wchar_t sizes.  */
1cefc9
   int no_wchar_size_warning;
1cefc9
+
1cefc9
+  /* All GNU_PROPERTY_AARCH64_FEATURE_1_AND properties.  */
1cefc9
+  uint32_t gnu_and_prop;
1cefc9
 };
1cefc9
 
1cefc9
 #define elf_aarch64_tdata(bfd)				\
1cefc9
@@ -9311,6 +9314,32 @@ elfNN_aarch64_backend_symbol_processing
1cefc9
     sym->flags |= BSF_KEEP;
1cefc9
 }
1cefc9
 
1cefc9
+/* Implement elf_backend_setup_gnu_properties for AArch64.  It serves as a
1cefc9
+   wrapper function for _bfd_aarch64_elf_link_setup_gnu_properties to account
1cefc9
+   for the effect of GNU properties of the output_bfd.  */
1cefc9
+static bfd *
1cefc9
+elfNN_aarch64_link_setup_gnu_properties (struct bfd_link_info *info)
1cefc9
+{
1cefc9
+  uint32_t prop = elf_aarch64_tdata (info->output_bfd)->gnu_and_prop;
1cefc9
+  bfd *pbfd = _bfd_aarch64_elf_link_setup_gnu_properties (info, &prop);
1cefc9
+  elf_aarch64_tdata (info->output_bfd)->gnu_and_prop = prop;
1cefc9
+  return pbfd;
1cefc9
+}
1cefc9
+
1cefc9
+/* Implement elf_backend_merge_gnu_properties for AArch64.  It serves as a
1cefc9
+   wrapper function for _bfd_aarch64_elf_merge_gnu_properties to account
1cefc9
+   for the effect of GNU properties of the output_bfd.  */
1cefc9
+static bfd_boolean
1cefc9
+elfNN_aarch64_merge_gnu_properties (struct bfd_link_info *info,
1cefc9
+				       bfd *abfd,
1cefc9
+				       elf_property *aprop,
1cefc9
+				       elf_property *bprop)
1cefc9
+{
1cefc9
+  uint32_t prop
1cefc9
+    = elf_aarch64_tdata (info->output_bfd)->gnu_and_prop;
1cefc9
+  return  _bfd_aarch64_elf_merge_gnu_properties (info, abfd, aprop,
1cefc9
+						 bprop, prop);
1cefc9
+}
1cefc9
 
1cefc9
 /* We use this so we can override certain functions
1cefc9
    (though currently we don't).  */
1cefc9
@@ -9453,6 +9482,12 @@ const struct elf_size_info elfNN_aarch64
1cefc9
 #define elf_backend_symbol_processing		\
1cefc9
   elfNN_aarch64_backend_symbol_processing
1cefc9
 
1cefc9
+#define elf_backend_setup_gnu_properties	\
1cefc9
+  elfNN_aarch64_link_setup_gnu_properties
1cefc9
+
1cefc9
+#define elf_backend_merge_gnu_properties	\
1cefc9
+  elfNN_aarch64_merge_gnu_properties
1cefc9
+
1cefc9
 #define elf_backend_can_refcount       1
1cefc9
 #define elf_backend_can_gc_sections    1
1cefc9
 #define elf_backend_plt_readonly       1
1cefc9
diff -rup binutils.orig/bfd/elfxx-aarch64.c binutils-2.30/bfd/elfxx-aarch64.c
1cefc9
--- binutils.orig/bfd/elfxx-aarch64.c	2020-11-04 14:53:52.138476401 +0000
1cefc9
+++ binutils-2.30/bfd/elfxx-aarch64.c	2020-11-04 14:56:42.276422492 +0000
1cefc9
@@ -660,3 +660,183 @@ _bfd_aarch64_elf_write_core_note (bfd *a
1cefc9
       }
1cefc9
     }
1cefc9
 }
1cefc9
+
1cefc9
+/* Find the first input bfd with GNU property and merge it with GPROP.  If no
1cefc9
+   such input is found, add it to a new section at the last input.  Update
1cefc9
+   GPROP accordingly.  */
1cefc9
+bfd *
1cefc9
+_bfd_aarch64_elf_link_setup_gnu_properties (struct bfd_link_info *info,
1cefc9
+					    uint32_t *gprop)
1cefc9
+{
1cefc9
+  asection *sec;
1cefc9
+  bfd *pbfd;
1cefc9
+  bfd *ebfd = NULL;
1cefc9
+  elf_property *prop;
1cefc9
+
1cefc9
+  uint32_t gnu_prop = *gprop;
1cefc9
+
1cefc9
+  /* Find a normal input file with GNU property note.  */
1cefc9
+  for (pbfd = info->input_bfds;
1cefc9
+       pbfd != NULL;
1cefc9
+       pbfd = pbfd->link.next)
1cefc9
+    if (bfd_get_flavour (pbfd) == bfd_target_elf_flavour
1cefc9
+	&& bfd_count_sections (pbfd) != 0)
1cefc9
+      {
1cefc9
+	ebfd = pbfd;
1cefc9
+
1cefc9
+	if (elf_properties (pbfd) != NULL)
1cefc9
+	  break;
1cefc9
+      }
1cefc9
+
1cefc9
+  /* If ebfd != NULL it is either an input with property note or the last
1cefc9
+     input.  Either way if we have gnu_prop, we should add it (by creating
1cefc9
+     a section if needed).  */
1cefc9
+  if (ebfd != NULL && gnu_prop)
1cefc9
+    {
1cefc9
+      prop = _bfd_elf_get_property (ebfd,
1cefc9
+				    GNU_PROPERTY_AARCH64_FEATURE_1_AND,
1cefc9
+				    4);
1cefc9
+      prop->u.number |= gnu_prop;
1cefc9
+      prop->pr_kind = property_number;
1cefc9
+
1cefc9
+      /* pbfd being NULL implies ebfd is the last input.  Create the GNU
1cefc9
+	 property note section.  */
1cefc9
+      if (pbfd == NULL)
1cefc9
+	{
1cefc9
+	  sec = bfd_make_section_with_flags (ebfd,
1cefc9
+					     NOTE_GNU_PROPERTY_SECTION_NAME,
1cefc9
+					     (SEC_ALLOC
1cefc9
+					      | SEC_LOAD
1cefc9
+					      | SEC_IN_MEMORY
1cefc9
+					      | SEC_READONLY
1cefc9
+					      | SEC_HAS_CONTENTS
1cefc9
+					      | SEC_DATA));
1cefc9
+	  if (sec == NULL)
1cefc9
+	    info->callbacks->einfo (
1cefc9
+	      _("%F%P: failed to create GNU property section\n"));
1cefc9
+
1cefc9
+	  elf_section_type (sec) = SHT_NOTE;
1cefc9
+	}
1cefc9
+    }
1cefc9
+
1cefc9
+  pbfd = _bfd_elf_link_setup_gnu_properties (info);
1cefc9
+
1cefc9
+  if (bfd_link_relocatable (info))
1cefc9
+    return pbfd;
1cefc9
+
1cefc9
+  /* If pbfd has any GNU_PROPERTY_AARCH64_FEATURE_1_AND properties, update
1cefc9
+     gnu_prop accordingly.  */
1cefc9
+  if (pbfd != NULL)
1cefc9
+    {
1cefc9
+      elf_property_list *p;
1cefc9
+
1cefc9
+      /* The property list is sorted in order of type.  */
1cefc9
+      for (p = elf_properties (pbfd); p; p = p->next)
1cefc9
+	{
1cefc9
+	  /* Check for all GNU_PROPERTY_AARCH64_FEATURE_1_AND.  */
1cefc9
+	  if (GNU_PROPERTY_AARCH64_FEATURE_1_AND == p->property.pr_type)
1cefc9
+	    {
1cefc9
+	      gnu_prop = (p->property.u.number
1cefc9
+			  & (GNU_PROPERTY_AARCH64_FEATURE_1_PAC
1cefc9
+			      | GNU_PROPERTY_AARCH64_FEATURE_1_BTI));
1cefc9
+	      break;
1cefc9
+	    }
1cefc9
+	  else if (GNU_PROPERTY_AARCH64_FEATURE_1_AND < p->property.pr_type)
1cefc9
+	    break;
1cefc9
+	}
1cefc9
+    }
1cefc9
+  *gprop = gnu_prop;
1cefc9
+  return pbfd;
1cefc9
+}
1cefc9
+
1cefc9
+/* Define elf_backend_parse_gnu_properties for AArch64.  */
1cefc9
+enum elf_property_kind
1cefc9
+_bfd_aarch64_elf_parse_gnu_properties (bfd *abfd, unsigned int type,
1cefc9
+				       bfd_byte *ptr, unsigned int datasz)
1cefc9
+{
1cefc9
+  elf_property *prop;
1cefc9
+
1cefc9
+  switch (type)
1cefc9
+    {
1cefc9
+    case GNU_PROPERTY_AARCH64_FEATURE_1_AND:
1cefc9
+      if (datasz != 4)
1cefc9
+	{
1cefc9
+	  _bfd_error_handler
1cefc9
+	    ( _("error: %pB: <corrupt AArch64 used size: 0x%x>"),
1cefc9
+	     abfd, datasz);
1cefc9
+	  return property_corrupt;
1cefc9
+	}
1cefc9
+      prop = _bfd_elf_get_property (abfd, type, datasz);
1cefc9
+      /* Combine properties of the same type.  */
1cefc9
+      prop->u.number |= bfd_h_get_32 (abfd, ptr);
1cefc9
+      prop->pr_kind = property_number;
1cefc9
+      break;
1cefc9
+
1cefc9
+    default:
1cefc9
+      return property_ignored;
1cefc9
+    }
1cefc9
+
1cefc9
+  return property_number;
1cefc9
+}
1cefc9
+
1cefc9
+/* Merge AArch64 GNU property BPROP with APROP also accounting for PROP.
1cefc9
+   If APROP isn't NULL, merge it with BPROP and/or PROP.  Vice-versa if BROP
1cefc9
+   isn't NULL.  Return TRUE if there is any update to APROP or if BPROP should
1cefc9
+   be merge with ABFD.  */
1cefc9
+bfd_boolean
1cefc9
+_bfd_aarch64_elf_merge_gnu_properties (struct bfd_link_info *info
1cefc9
+				       ATTRIBUTE_UNUSED,
1cefc9
+				       bfd *abfd ATTRIBUTE_UNUSED,
1cefc9
+				       elf_property *aprop,
1cefc9
+				       elf_property *bprop,
1cefc9
+				       uint32_t prop)
1cefc9
+{
1cefc9
+  unsigned int orig_number;
1cefc9
+  bfd_boolean updated = FALSE;
1cefc9
+  unsigned int pr_type = aprop != NULL ? aprop->pr_type : bprop->pr_type;
1cefc9
+
1cefc9
+  switch (pr_type)
1cefc9
+    {
1cefc9
+    case GNU_PROPERTY_AARCH64_FEATURE_1_AND:
1cefc9
+      {
1cefc9
+	if (aprop != NULL && bprop != NULL)
1cefc9
+	  {
1cefc9
+	    orig_number = aprop->u.number;
1cefc9
+	    aprop->u.number = (orig_number & bprop->u.number) | prop;
1cefc9
+	    updated = orig_number != aprop->u.number;
1cefc9
+	    /* Remove the property if all feature bits are cleared.  */
1cefc9
+	    if (aprop->u.number == 0)
1cefc9
+	      aprop->pr_kind = property_remove;
1cefc9
+	    break;
1cefc9
+	  }
1cefc9
+	/* If either is NULL, the AND would be 0 so, if there is
1cefc9
+	   any PROP, asign it to the input that is not NULL.  */
1cefc9
+	if (prop)
1cefc9
+	  {
1cefc9
+	    if (aprop != NULL)
1cefc9
+	      {
1cefc9
+		orig_number = aprop->u.number;
1cefc9
+		aprop->u.number = prop;
1cefc9
+		updated = orig_number != aprop->u.number;
1cefc9
+	      }
1cefc9
+	    else
1cefc9
+	      {
1cefc9
+		bprop->u.number = prop;
1cefc9
+		updated = TRUE;
1cefc9
+	      }
1cefc9
+	  }
1cefc9
+	/* No PROP and BPROP is NULL, so remove APROP.  */
1cefc9
+	else if (aprop != NULL)
1cefc9
+	  {
1cefc9
+	    aprop->pr_kind = property_remove;
1cefc9
+	    updated = TRUE;
1cefc9
+	  }
1cefc9
+      }
1cefc9
+      break;
1cefc9
+
1cefc9
+    default:
1cefc9
+      abort ();
1cefc9
+    }
1cefc9
+
1cefc9
+  return updated;
1cefc9
+}
1cefc9
diff -rup binutils.orig/bfd/elfxx-aarch64.h binutils-2.30/bfd/elfxx-aarch64.h
1cefc9
--- binutils.orig/bfd/elfxx-aarch64.h	2020-11-04 14:53:52.134476424 +0000
1cefc9
+++ binutils-2.30/bfd/elfxx-aarch64.h	2020-11-04 14:56:42.276422492 +0000
1cefc9
@@ -65,3 +65,19 @@ _bfd_aarch64_elf_write_core_note (bfd *,
1cefc9
 #define elf_backend_grok_prstatus	_bfd_aarch64_elf_grok_prstatus
1cefc9
 #define elf_backend_grok_psinfo		_bfd_aarch64_elf_grok_psinfo
1cefc9
 #define elf_backend_write_core_note	_bfd_aarch64_elf_write_core_note
1cefc9
+
1cefc9
+extern bfd *
1cefc9
+_bfd_aarch64_elf_link_setup_gnu_properties (struct bfd_link_info *,
1cefc9
+					    uint32_t *);
1cefc9
+
1cefc9
+extern enum elf_property_kind
1cefc9
+_bfd_aarch64_elf_parse_gnu_properties (bfd *, unsigned int,
1cefc9
+				       bfd_byte *, unsigned int);
1cefc9
+
1cefc9
+extern bfd_boolean
1cefc9
+_bfd_aarch64_elf_merge_gnu_properties (struct bfd_link_info *, bfd *,
1cefc9
+				       elf_property *, elf_property *,
1cefc9
+				       uint32_t);
1cefc9
+
1cefc9
+#define elf_backend_parse_gnu_properties	\
1cefc9
+  _bfd_aarch64_elf_parse_gnu_properties
1cefc9
diff -rup binutils.orig/binutils/readelf.c binutils-2.30/binutils/readelf.c
1cefc9
--- binutils.orig/binutils/readelf.c	2020-11-04 14:53:51.723478764 +0000
1cefc9
+++ binutils-2.30/binutils/readelf.c	2020-11-04 14:56:42.277422485 +0000
1cefc9
@@ -17103,6 +17103,33 @@ decode_x86_feature_2 (unsigned int bitma
1cefc9
 }
1cefc9
 
1cefc9
 static void
1cefc9
+decode_aarch64_feature_1_and (unsigned int bitmask)
1cefc9
+{
1cefc9
+  while (bitmask)
1cefc9
+    {
1cefc9
+      unsigned int bit = bitmask & (- bitmask);
1cefc9
+
1cefc9
+      bitmask &= ~ bit;
1cefc9
+      switch (bit)
1cefc9
+	{
1cefc9
+	case GNU_PROPERTY_AARCH64_FEATURE_1_BTI:
1cefc9
+	  printf ("BTI");
1cefc9
+	  break;
1cefc9
+
1cefc9
+	case GNU_PROPERTY_AARCH64_FEATURE_1_PAC:
1cefc9
+	  printf ("PAC");
1cefc9
+	  break;
1cefc9
+
1cefc9
+	default:
1cefc9
+	  printf (_("<unknown: %x>"), bit);
1cefc9
+	  break;
1cefc9
+	}
1cefc9
+      if (bitmask)
1cefc9
+	printf (", ");
1cefc9
+    }
1cefc9
+}
1cefc9
+
1cefc9
+static void
1cefc9
 print_gnu_property_note (Filedata * filedata, Elf_Internal_Note * pnote)
1cefc9
 {
1cefc9
   unsigned char * ptr = (unsigned char *) pnote->descdata;
1cefc9
@@ -17236,6 +17263,18 @@ print_gnu_property_note (Filedata * file
1cefc9
 		  break;
1cefc9
 		}
1cefc9
 	    }
1cefc9
+	  else if (filedata->file_header.e_machine == EM_AARCH64)
1cefc9
+	    {
1cefc9
+	      if (type == GNU_PROPERTY_AARCH64_FEATURE_1_AND)
1cefc9
+		{
1cefc9
+		  printf ("AArch64 feature: ");
1cefc9
+		  if (datasz != 4)
1cefc9
+		    printf (_("<corrupt length: %#x> "), datasz);
1cefc9
+		  else
1cefc9
+		    decode_aarch64_feature_1_and (byte_get (ptr, 4));
1cefc9
+		  goto next;
1cefc9
+		}
1cefc9
+	    }
1cefc9
 	}
1cefc9
       else
1cefc9
 	{
1cefc9
diff -rup binutils.orig/include/elf/common.h binutils-2.30/include/elf/common.h
1cefc9
--- binutils.orig/include/elf/common.h	2020-11-04 14:53:52.155476304 +0000
1cefc9
+++ binutils-2.30/include/elf/common.h	2020-11-04 14:56:42.277422485 +0000
1cefc9
@@ -832,6 +832,12 @@
1cefc9
 #define GNU_PROPERTY_X86_FEATURE_2_XSAVEOPT	(1U << 8)
1cefc9
 #define GNU_PROPERTY_X86_FEATURE_2_XSAVEC	(1U << 9)
1cefc9
 
1cefc9
+/* AArch64 specific GNU PROPERTY.  */
1cefc9
+#define GNU_PROPERTY_AARCH64_FEATURE_1_AND	0xc0000000
1cefc9
+
1cefc9
+#define GNU_PROPERTY_AARCH64_FEATURE_1_BTI	(1U << 0)
1cefc9
+#define GNU_PROPERTY_AARCH64_FEATURE_1_PAC	(1U << 1)
1cefc9
+
1cefc9
 /* Values used in GNU .note.ABI-tag notes (NT_GNU_ABI_TAG).  */
1cefc9
 #define GNU_ABI_TAG_LINUX	0
1cefc9
 #define GNU_ABI_TAG_HURD	1
1cefc9
diff -rup binutils.orig/ld/testsuite/ld-aarch64/aarch64-elf.exp binutils-2.30/ld/testsuite/ld-aarch64/aarch64-elf.exp
1cefc9
--- binutils.orig/ld/testsuite/ld-aarch64/aarch64-elf.exp	2020-11-04 14:53:51.843478081 +0000
1cefc9
+++ binutils-2.30/ld/testsuite/ld-aarch64/aarch64-elf.exp	2020-11-04 14:56:42.278422479 +0000
1cefc9
@@ -337,6 +337,10 @@ run_dump_test_lp64 "variant_pcs-r"
1cefc9
 run_dump_test_lp64 "variant_pcs-shared"
1cefc9
 run_dump_test_lp64 "variant_pcs-now"
1cefc9
 
1cefc9
+run_dump_test "property-bti-pac1"
1cefc9
+run_dump_test "property-bti-pac2"
1cefc9
+run_dump_test "property-bti-pac3"
1cefc9
+
1cefc9
 set aarch64elflinktests {
1cefc9
   {"ld-aarch64/so with global symbol" "-shared" "" "" {copy-reloc-so.s}
1cefc9
     {} "copy-reloc-so.so"}
1cefc9
--- /dev/null	2020-11-04 08:04:13.849482156 +0000
1cefc9
+++ binutils-2.30/ld/testsuite/ld-aarch64/property-bti-pac1.d	2020-11-04 14:56:42.278422479 +0000
1cefc9
@@ -0,0 +1,11 @@
1cefc9
+#name: GNU Property (single input, combine section)
1cefc9
+#source: property-bti-pac1.s
1cefc9
+#as: -march=armv8.5-a -defsym __mult__=0
1cefc9
+#ld: -shared
1cefc9
+#readelf: -n
1cefc9
+#target: *linux*
1cefc9
+
1cefc9
+Displaying notes found in: .note.gnu.property
1cefc9
+  Owner                 Data size	Description
1cefc9
+  GNU                  0x00000010	NT_GNU_PROPERTY_TYPE_0
1cefc9
+      Properties: AArch64 feature: BTI, PAC
1cefc9
--- /dev/null	2020-11-04 08:04:13.849482156 +0000
1cefc9
+++ binutils-2.30/ld/testsuite/ld-aarch64/property-bti-pac1.s	2020-11-04 14:56:42.278422479 +0000
1cefc9
@@ -0,0 +1,37 @@
1cefc9
+	.text
1cefc9
+	.globl _start
1cefc9
+	.type _start,@function
1cefc9
+_start:
1cefc9
+	mov x1, #2
1cefc9
+.ifndef __mult__
1cefc9
+	bl foo
1cefc9
+.endif
1cefc9
+	.section ".note.gnu.property", "a"
1cefc9
+	.p2align 3
1cefc9
+	.long 1f - 0f		/* name length */
1cefc9
+	.long 5f - 2f		/* data length */
1cefc9
+	.long 5			/* note type */
1cefc9
+0:	.asciz "GNU"		/* vendor name */
1cefc9
+1:
1cefc9
+	.p2align 3
1cefc9
+2:	.long 0xc0000000	/* pr_type.  */
1cefc9
+	.long 4f - 3f		/* pr_datasz.  */
1cefc9
+3:
1cefc9
+	.long 0x2		/* PAC.  */
1cefc9
+4:
1cefc9
+	.p2align 3
1cefc9
+5:
1cefc9
+	.p2align 3
1cefc9
+	.long 1f - 0f		/* name length */
1cefc9
+	.long 5f - 2f		/* data length */
1cefc9
+	.long 5			/* note type */
1cefc9
+0:	.asciz "GNU"		/* vendor name */
1cefc9
+1:
1cefc9
+	.p2align 3
1cefc9
+2:	.long 0xc0000000	/* pr_type.  */
1cefc9
+	.long 4f - 3f		/* pr_datasz.  */
1cefc9
+3:
1cefc9
+	.long 0x1		/* BTI.  */
1cefc9
+4:
1cefc9
+	.p2align 3
1cefc9
+5:
1cefc9
--- /dev/null	2020-11-04 08:04:13.849482156 +0000
1cefc9
+++ binutils-2.30/ld/testsuite/ld-aarch64/property-bti-pac2.s	2020-11-04 14:56:42.278422479 +0000
1cefc9
@@ -0,0 +1,50 @@
1cefc9
+	.text
1cefc9
+	.global	foo
1cefc9
+	.type	foo, %function
1cefc9
+foo:
1cefc9
+	sub	sp, sp, #16
1cefc9
+	mov	w0, 9
1cefc9
+	str	w0, [sp, 12]
1cefc9
+	ldr	w0, [sp, 12]
1cefc9
+	add	w0, w0, 4
1cefc9
+	str	w0, [sp, 12]
1cefc9
+	nop
1cefc9
+	add	sp, sp, 16
1cefc9
+	ret
1cefc9
+	.size	foo, .-foo
1cefc9
+	.global	bar
1cefc9
+	.type	bar, %function
1cefc9
+.ifdef __property_bti__
1cefc9
+	.section ".note.gnu.property", "a"
1cefc9
+	.p2align 3
1cefc9
+	.long 1f - 0f		/* name length */
1cefc9
+	.long 5f - 2f		/* data length */
1cefc9
+	.long 5			/* note type */
1cefc9
+0:	.asciz "GNU"		/* vendor name */
1cefc9
+1:
1cefc9
+	.p2align 3
1cefc9
+2:	.long 0xc0000000	/* pr_type.  */
1cefc9
+	.long 4f - 3f		/* pr_datasz.  */
1cefc9
+3:
1cefc9
+	.long 0x1		/* BTI.  */
1cefc9
+4:
1cefc9
+	.p2align 3
1cefc9
+5:
1cefc9
+.endif
1cefc9
+.ifdef __property_pac__
1cefc9
+	.section ".note.gnu.property", "a"
1cefc9
+	.p2align 3
1cefc9
+	.long 1f - 0f		/* name length */
1cefc9
+	.long 5f - 2f		/* data length */
1cefc9
+	.long 5			/* note type */
1cefc9
+0:	.asciz "GNU"		/* vendor name */
1cefc9
+1:
1cefc9
+	.p2align 3
1cefc9
+2:	.long 0xc0000000	/* pr_type.  */
1cefc9
+	.long 4f - 3f		/* pr_datasz.  */
1cefc9
+3:
1cefc9
+	.long 0x2		/* PAC.  */
1cefc9
+4:
1cefc9
+	.p2align 3
1cefc9
+5:
1cefc9
+.endif
1cefc9
--- /dev/null	2020-11-04 08:04:13.849482156 +0000
1cefc9
+++ binutils-2.30/ld/testsuite/ld-aarch64/property-bti-pac2.d	2020-11-04 14:56:42.278422479 +0000
1cefc9
@@ -0,0 +1,12 @@
1cefc9
+#name: GNU Property (combine multiple with BTI)
1cefc9
+#source: property-bti-pac1.s
1cefc9
+#source: property-bti-pac2.s
1cefc9
+#as: -mabi=lp64 -defsym __property_bti__=1
1cefc9
+#ld: -e _start
1cefc9
+#readelf: -n
1cefc9
+#target: *linux*
1cefc9
+
1cefc9
+Displaying notes found in: .note.gnu.property
1cefc9
+  Owner                 Data size	Description
1cefc9
+  GNU                  0x00000010	NT_GNU_PROPERTY_TYPE_0
1cefc9
+      Properties: AArch64 feature: BTI
1cefc9
--- /dev/null	2020-11-04 08:04:13.849482156 +0000
1cefc9
+++ binutils-2.30/ld/testsuite/ld-aarch64/property-bti-pac3.d	2020-11-04 14:56:42.278422479 +0000
1cefc9
@@ -0,0 +1,12 @@
1cefc9
+#name: GNU Property (combine multiple with PAC)
1cefc9
+#source: property-bti-pac1.s
1cefc9
+#source: property-bti-pac2.s
1cefc9
+#as: -mabi=lp64 -defsym __property_pac__=1
1cefc9
+#ld: -e _start
1cefc9
+#readelf: -n
1cefc9
+#target: *linux*
1cefc9
+
1cefc9
+Displaying notes found in: .note.gnu.property
1cefc9
+  Owner                 Data size	Description
1cefc9
+  GNU                  0x00000010	NT_GNU_PROPERTY_TYPE_0
1cefc9
+      Properties: AArch64 feature: PAC
1cefc9
diff -rup binutils.orig/bfd/elfnn-aarch64.c binutils-2.30/bfd/elfnn-aarch64.c
1cefc9
--- binutils.orig/bfd/elfnn-aarch64.c	2020-11-25 11:53:26.648275978 +0000
1cefc9
+++ binutils-2.30/bfd/elfnn-aarch64.c	2020-11-25 12:21:39.276864970 +0000
1cefc9
@@ -9331,12 +9331,14 @@ elfNN_aarch64_link_setup_gnu_properties
1cefc9
    for the effect of GNU properties of the output_bfd.  */
1cefc9
 static bfd_boolean
1cefc9
 elfNN_aarch64_merge_gnu_properties (struct bfd_link_info *info,
1cefc9
-				       bfd *abfd,
1cefc9
-				       elf_property *aprop,
1cefc9
-				       elf_property *bprop)
1cefc9
+				    bfd *abfd,
1cefc9
+				    bfd *bbfd ATTRIBUTE_UNUSED,
1cefc9
+				    elf_property *aprop,
1cefc9
+				    elf_property *bprop)
1cefc9
 {
1cefc9
   uint32_t prop
1cefc9
     = elf_aarch64_tdata (info->output_bfd)->gnu_and_prop;
1cefc9
+
1cefc9
   return  _bfd_aarch64_elf_merge_gnu_properties (info, abfd, aprop,
1cefc9
 						 bprop, prop);
1cefc9
 }
1cefc9
diff -rup binutils.orig/bfd/elfxx-aarch64.c binutils-2.30/bfd/elfxx-aarch64.c
1cefc9
--- binutils.orig/bfd/elfxx-aarch64.c	2020-11-25 11:53:26.655275930 +0000
1cefc9
+++ binutils-2.30/bfd/elfxx-aarch64.c	2020-11-25 12:21:34.689895875 +0000
1cefc9
@@ -22,6 +22,7 @@
1cefc9
 #include "elfxx-aarch64.h"
1cefc9
 #include <stdarg.h>
1cefc9
 #include <string.h>
1cefc9
+#include "libbfd.h"
1cefc9
 
1cefc9
 #define MASK(n) ((1u << (n)) - 1)
1cefc9
 
1cefc9
@@ -835,7 +836,10 @@ _bfd_aarch64_elf_merge_gnu_properties (s
1cefc9
       break;
1cefc9
 
1cefc9
     default:
1cefc9
-      abort ();
1cefc9
+      _bfd_error_handler
1cefc9
+	( _("error: %pB: <corrupt AArch64 property note: 0x%x>"),
1cefc9
+	  abfd, pr_type);
1cefc9
+      return FALSE;
1cefc9
     }
1cefc9
 
1cefc9
   return updated;
1cefc9
diff -rup binutils.orig/ld/testsuite/ld-aarch64/property-bti-pac1.d binutils-2.30/ld/testsuite/ld-aarch64/property-bti-pac1.d
1cefc9
--- binutils.orig/ld/testsuite/ld-aarch64/property-bti-pac1.d	2020-11-25 11:53:26.344278044 +0000
1cefc9
+++ binutils-2.30/ld/testsuite/ld-aarch64/property-bti-pac1.d	2020-11-25 11:57:53.179471900 +0000
1cefc9
@@ -1,6 +1,6 @@
1cefc9
 #name: GNU Property (single input, combine section)
1cefc9
 #source: property-bti-pac1.s
1cefc9
-#as: -march=armv8.5-a -defsym __mult__=0
1cefc9
+#as: -defsym __mult__=0
1cefc9
 #ld: -shared
1cefc9
 #readelf: -n
1cefc9
 #target: *linux*