[BFD, LD, AArch64, 1/3] Add support for GNU PROPERTIES in AArch64 for BTI and PAC
authorSudakshina Das <sudi.das@arm.com>
Wed, 13 Mar 2019 10:42:27 +0000 (10:42 +0000)
committerSudakshina Das <sudi.das@arm.com>
Wed, 13 Mar 2019 11:47:00 +0000 (11:47 +0000)
This is part of the patch series to add support for BTI and
PAC in AArch64 linker.

This patch implements the following:
1) This extends in the gnu property support in the linker for
AArch64 by defining backend hooks for elf_backend_setup_gnu_properties,
elf_backend_merge_gnu_properties and elf_backend_parse_gnu_properties.
2) It defines AArch64 specific GNU property
GNU_PROPERTY_AARCH64_FEATURE_1_AND and 2 bit for BTI and PAC in it.
3) It also adds support in readelf.c to read and print these new
GNU properties in AArch64.
All these are made according to the new AArch64 ELF ABI
https://developer.arm.com/docs/ihi0056/latest/elf-for-the-arm-64-bit-architecture-aarch64-abi-2018q4

*** bfd/ChangeLog ***

2019-03-13  Sudakshina Das  <sudi.das@arm.com>

* elf-properties.c (_bfd_elf_link_setup_gnu_properties): Exclude
linker created inputs from merge.
* elfnn-aarch64.c (struct elf_aarch64_obj_tdata): Add field for
GNU_PROPERTY_AARCH64_FEATURE_1_AND properties.
(elfNN_aarch64_link_setup_gnu_properties): New.
(elfNN_aarch64_merge_gnu_properties): New.
(elf_backend_setup_gnu_properties): Define for AArch64.
(elf_backend_merge_gnu_properties): Likewise.
* elfxx-aarch64.c (_bfd_aarch64_elf_link_setup_gnu_properties): Define.
(_bfd_aarch64_elf_parse_gnu_properties): Define.
(_bfd_aarch64_elf_merge_gnu_properties): Define.
* elfxx-aarch64.h (_bfd_aarch64_elf_link_setup_gnu_properties): Declare.
(_bfd_aarch64_elf_parse_gnu_properties): Declare.
(_bfd_aarch64_elf_merge_gnu_properties): Declare.
(elf_backend_parse_gnu_properties): Define for AArch64.

*** binutils/ChangeLog ***

2019-03-13  Sudakshina Das  <sudi.das@arm.com>

* readelf.c (decode_aarch64_feature_1_and): New.
(print_gnu_property_note): Add case for AArch64 gnu notes.

*** include/ChangeLog ***

2019-03-13  Sudakshina Das  <sudi.das@arm.com>

* elf/common.h (GNU_PROPERTY_AARCH64_FEATURE_1_AND): New.
(GNU_PROPERTY_AARCH64_FEATURE_1_BTI): New.
(GNU_PROPERTY_AARCH64_FEATURE_1_PAC): New.

*** ld/ChangeLog ***

2019-03-13  Sudakshina Das  <sudi.das@arm.com>

* NEWS: Document GNU_PROPERTY_AARCH64_FEATURE_1_BTI and
GNU_PROPERTY_AARCH64_FEATURE_1_PAC.
* testsuite/ld-aarch64/aarch64-elf.exp: Add run commands for new tests.
* testsuite/ld-aarch64/property-bti-pac1.d: New test.
* testsuite/ld-aarch64/property-bti-pac1.s: New test.
* testsuite/ld-aarch64/property-bti-pac2.d: New test.
* testsuite/ld-aarch64/property-bti-pac2.s: New test.
* testsuite/ld-aarch64/property-bti-pac3.d: New test.

17 files changed:
bfd/ChangeLog
bfd/elf-properties.c
bfd/elfnn-aarch64.c
bfd/elfxx-aarch64.c
bfd/elfxx-aarch64.h
binutils/ChangeLog
binutils/readelf.c
include/ChangeLog
include/elf/common.h
ld/ChangeLog
ld/NEWS
ld/testsuite/ld-aarch64/aarch64-elf.exp
ld/testsuite/ld-aarch64/property-bti-pac1.d [new file with mode: 0644]
ld/testsuite/ld-aarch64/property-bti-pac1.s [new file with mode: 0644]
ld/testsuite/ld-aarch64/property-bti-pac2.d [new file with mode: 0644]
ld/testsuite/ld-aarch64/property-bti-pac2.s [new file with mode: 0644]
ld/testsuite/ld-aarch64/property-bti-pac3.d [new file with mode: 0644]

index 39b5500364236e8f3835dccb0841f9f510ab0eb7..3e5c7c25c5687c4632567e5f39533ef991b896a3 100644 (file)
@@ -1,3 +1,21 @@
+2019-03-13  Sudakshina Das  <sudi.das@arm.com>
+
+       * elf-properties.c (_bfd_elf_link_setup_gnu_properties): Exclude
+       linker created inputs from merge.
+       * elfnn-aarch64.c (struct elf_aarch64_obj_tdata): Add field for
+       GNU_PROPERTY_AARCH64_FEATURE_1_AND properties.
+       (elfNN_aarch64_link_setup_gnu_properties): New.
+       (elfNN_aarch64_merge_gnu_properties): New.
+       (elf_backend_setup_gnu_properties): Define for AArch64.
+       (elf_backend_merge_gnu_properties): Likewise.
+       * elfxx-aarch64.c (_bfd_aarch64_elf_link_setup_gnu_properties): Define.
+       (_bfd_aarch64_elf_parse_gnu_properties): Define.
+       (_bfd_aarch64_elf_merge_gnu_properties): Define.
+       * elfxx-aarch64.h (_bfd_aarch64_elf_link_setup_gnu_properties): Declare.
+       (_bfd_aarch64_elf_parse_gnu_properties): Declare.
+       (_bfd_aarch64_elf_merge_gnu_properties): Declare.
+       (elf_backend_parse_gnu_properties): Define for AArch64.
+
 2019-03-13  H.J. Lu  <hongjiu.lu@intel.com>
 
        PR ld/24322
index 5e48d75faa2694538cbbb74af0a86bfe85da3fd3..0c3f19ce56a36bb18d9afd2e140d735eeaf9c6a9 100644 (file)
@@ -555,7 +555,7 @@ _bfd_elf_link_setup_gnu_properties (struct bfd_link_info *info)
 
   for (abfd = info->input_bfds; abfd != NULL; abfd = abfd->link.next)
     if (abfd != first_pbfd
-       && (abfd->flags & (DYNAMIC | BFD_PLUGIN)) == 0)
+       && (abfd->flags & (DYNAMIC | BFD_PLUGIN | BFD_LINKER_CREATED)) == 0)
       {
        elf_property_list *null_ptr = NULL;
        elf_property_list **listp = &null_ptr;
index faa27611d466ce75e5c02d8bbcfca6459618d4bd..5b8cc4c9701feacd0deb5c998c89d17d97864646 100644 (file)
@@ -2435,6 +2435,9 @@ struct elf_aarch64_obj_tdata
 
   /* Zero to warn when linking objects with incompatible wchar_t sizes.  */
   int no_wchar_size_warning;
+
+  /* All GNU_PROPERTY_AARCH64_FEATURE_1_AND properties.  */
+  uint32_t gnu_and_prop;
 };
 
 #define elf_aarch64_tdata(bfd)                         \
@@ -9615,6 +9618,32 @@ elfNN_aarch64_backend_symbol_processing (bfd *abfd, asymbol *sym)
     sym->flags |= BSF_KEEP;
 }
 
+/* Implement elf_backend_setup_gnu_properties for AArch64.  It serves as a
+   wrapper function for _bfd_aarch64_elf_link_setup_gnu_properties to account
+   for the effect of GNU properties of the output_bfd.  */
+static bfd *
+elfNN_aarch64_link_setup_gnu_properties (struct bfd_link_info *info)
+{
+  uint32_t prop = elf_aarch64_tdata (info->output_bfd)->gnu_and_prop;
+  bfd *pbfd = _bfd_aarch64_elf_link_setup_gnu_properties (info, &prop);
+  elf_aarch64_tdata (info->output_bfd)->gnu_and_prop = prop;
+  return pbfd;
+}
+
+/* Implement elf_backend_merge_gnu_properties for AArch64.  It serves as a
+   wrapper function for _bfd_aarch64_elf_merge_gnu_properties to account
+   for the effect of GNU properties of the output_bfd.  */
+static bfd_boolean
+elfNN_aarch64_merge_gnu_properties (struct bfd_link_info *info,
+                                      bfd *abfd,
+                                      elf_property *aprop,
+                                      elf_property *bprop)
+{
+  uint32_t prop
+    = elf_aarch64_tdata (info->output_bfd)->gnu_and_prop;
+  return  _bfd_aarch64_elf_merge_gnu_properties (info, abfd, aprop,
+                                                bprop, prop);
+}
 
 /* We use this so we can override certain functions
    (though currently we don't).  */
@@ -9754,6 +9783,12 @@ const struct elf_size_info elfNN_aarch64_size_info =
 #define elf_backend_symbol_processing          \
   elfNN_aarch64_backend_symbol_processing
 
+#define elf_backend_setup_gnu_properties       \
+  elfNN_aarch64_link_setup_gnu_properties
+
+#define elf_backend_merge_gnu_properties       \
+  elfNN_aarch64_merge_gnu_properties
+
 #define elf_backend_can_refcount       1
 #define elf_backend_can_gc_sections    1
 #define elf_backend_plt_readonly       1
index 32a9d972824d653785358f933a1157533f6e9779..cae94d03e8453de0cceee1619668fff71a609edf 100644 (file)
@@ -683,3 +683,183 @@ _bfd_aarch64_elf_write_core_note (bfd *abfd, char *buf, int *bufsiz, int note_ty
       }
     }
 }
+
+/* Find the first input bfd with GNU property and merge it with GPROP.  If no
+   such input is found, add it to a new section at the last input.  Update
+   GPROP accordingly.  */
+bfd *
+_bfd_aarch64_elf_link_setup_gnu_properties (struct bfd_link_info *info,
+                                           uint32_t *gprop)
+{
+  asection *sec;
+  bfd *pbfd;
+  bfd *ebfd = NULL;
+  elf_property *prop;
+
+  uint32_t gnu_prop = *gprop;
+
+  /* Find a normal input file with GNU property note.  */
+  for (pbfd = info->input_bfds;
+       pbfd != NULL;
+       pbfd = pbfd->link.next)
+    if (bfd_get_flavour (pbfd) == bfd_target_elf_flavour
+       && bfd_count_sections (pbfd) != 0)
+      {
+       ebfd = pbfd;
+
+       if (elf_properties (pbfd) != NULL)
+         break;
+      }
+
+  /* If ebfd != NULL it is either an input with property note or the last
+     input.  Either way if we have gnu_prop, we should add it (by creating
+     a section if needed).  */
+  if (ebfd != NULL && gnu_prop)
+    {
+      prop = _bfd_elf_get_property (ebfd,
+                                   GNU_PROPERTY_AARCH64_FEATURE_1_AND,
+                                   4);
+      prop->u.number |= gnu_prop;
+      prop->pr_kind = property_number;
+
+      /* pbfd being NULL implies ebfd is the last input.  Create the GNU
+        property note section.  */
+      if (pbfd == NULL)
+       {
+         sec = bfd_make_section_with_flags (ebfd,
+                                            NOTE_GNU_PROPERTY_SECTION_NAME,
+                                            (SEC_ALLOC
+                                             | SEC_LOAD
+                                             | SEC_IN_MEMORY
+                                             | SEC_READONLY
+                                             | SEC_HAS_CONTENTS
+                                             | SEC_DATA));
+         if (sec == NULL)
+           info->callbacks->einfo (
+             _("%F%P: failed to create GNU property section\n"));
+
+         elf_section_type (sec) = SHT_NOTE;
+       }
+    }
+
+  pbfd = _bfd_elf_link_setup_gnu_properties (info);
+
+  if (bfd_link_relocatable (info))
+    return pbfd;
+
+  /* If pbfd has any GNU_PROPERTY_AARCH64_FEATURE_1_AND properties, update
+     gnu_prop accordingly.  */
+  if (pbfd != NULL)
+    {
+      elf_property_list *p;
+
+      /* The property list is sorted in order of type.  */
+      for (p = elf_properties (pbfd); p; p = p->next)
+       {
+         /* Check for all GNU_PROPERTY_AARCH64_FEATURE_1_AND.  */
+         if (GNU_PROPERTY_AARCH64_FEATURE_1_AND == p->property.pr_type)
+           {
+             gnu_prop = (p->property.u.number
+                         & (GNU_PROPERTY_AARCH64_FEATURE_1_PAC
+                             | GNU_PROPERTY_AARCH64_FEATURE_1_BTI));
+             break;
+           }
+         else if (GNU_PROPERTY_AARCH64_FEATURE_1_AND < p->property.pr_type)
+           break;
+       }
+    }
+  *gprop = gnu_prop;
+  return pbfd;
+}
+
+/* Define elf_backend_parse_gnu_properties for AArch64.  */
+enum elf_property_kind
+_bfd_aarch64_elf_parse_gnu_properties (bfd *abfd, unsigned int type,
+                                      bfd_byte *ptr, unsigned int datasz)
+{
+  elf_property *prop;
+
+  switch (type)
+    {
+    case GNU_PROPERTY_AARCH64_FEATURE_1_AND:
+      if (datasz != 4)
+       {
+         _bfd_error_handler
+           ( _("error: %pB: <corrupt AArch64 used size: 0x%x>"),
+            abfd, datasz);
+         return property_corrupt;
+       }
+      prop = _bfd_elf_get_property (abfd, type, datasz);
+      /* Combine properties of the same type.  */
+      prop->u.number |= bfd_h_get_32 (abfd, ptr);
+      prop->pr_kind = property_number;
+      break;
+
+    default:
+      return property_ignored;
+    }
+
+  return property_number;
+}
+
+/* Merge AArch64 GNU property BPROP with APROP also accounting for PROP.
+   If APROP isn't NULL, merge it with BPROP and/or PROP.  Vice-versa if BROP
+   isn't NULL.  Return TRUE if there is any update to APROP or if BPROP should
+   be merge with ABFD.  */
+bfd_boolean
+_bfd_aarch64_elf_merge_gnu_properties (struct bfd_link_info *info
+                                      ATTRIBUTE_UNUSED,
+                                      bfd *abfd ATTRIBUTE_UNUSED,
+                                      elf_property *aprop,
+                                      elf_property *bprop,
+                                      uint32_t prop)
+{
+  unsigned int orig_number;
+  bfd_boolean updated = FALSE;
+  unsigned int pr_type = aprop != NULL ? aprop->pr_type : bprop->pr_type;
+
+  switch (pr_type)
+    {
+    case GNU_PROPERTY_AARCH64_FEATURE_1_AND:
+      {
+       if (aprop != NULL && bprop != NULL)
+         {
+           orig_number = aprop->u.number;
+           aprop->u.number = (orig_number & bprop->u.number) | prop;
+           updated = orig_number != aprop->u.number;
+           /* Remove the property if all feature bits are cleared.  */
+           if (aprop->u.number == 0)
+             aprop->pr_kind = property_remove;
+           break;
+         }
+       /* If either is NULL, the AND would be 0 so, if there is
+          any PROP, asign it to the input that is not NULL.  */
+       if (prop)
+         {
+           if (aprop != NULL)
+             {
+               orig_number = aprop->u.number;
+               aprop->u.number = prop;
+               updated = orig_number != aprop->u.number;
+             }
+           else
+             {
+               bprop->u.number = prop;
+               updated = TRUE;
+             }
+         }
+       /* No PROP and BPROP is NULL, so remove APROP.  */
+       else if (aprop != NULL)
+         {
+           aprop->pr_kind = property_remove;
+           updated = TRUE;
+         }
+      }
+      break;
+
+    default:
+      abort ();
+    }
+
+  return updated;
+}
index 1f9ce09675f5e21da4ddff5a1e72d75552110c3f..a6d1792687cf39a68beb3235f5875d50bfc3ad4e 100644 (file)
@@ -55,3 +55,19 @@ _bfd_aarch64_elf_write_core_note (bfd *, char *, int *, int, ...);
 #define elf_backend_grok_prstatus      _bfd_aarch64_elf_grok_prstatus
 #define elf_backend_grok_psinfo                _bfd_aarch64_elf_grok_psinfo
 #define elf_backend_write_core_note    _bfd_aarch64_elf_write_core_note
+
+extern bfd *
+_bfd_aarch64_elf_link_setup_gnu_properties (struct bfd_link_info *,
+                                           uint32_t *);
+
+extern enum elf_property_kind
+_bfd_aarch64_elf_parse_gnu_properties (bfd *, unsigned int,
+                                      bfd_byte *, unsigned int);
+
+extern bfd_boolean
+_bfd_aarch64_elf_merge_gnu_properties (struct bfd_link_info *, bfd *,
+                                      elf_property *, elf_property *,
+                                      uint32_t);
+
+#define elf_backend_parse_gnu_properties       \
+  _bfd_aarch64_elf_parse_gnu_properties
index d62f94a47cc6a8208c24fdd996c23b0c3e26f68b..894eb5590648da1bc07d2a8a943896806915c36d 100644 (file)
@@ -1,3 +1,8 @@
+2019-03-13  Sudakshina Das  <sudi.das@arm.com>
+
+       * readelf.c (decode_aarch64_feature_1_and): New.
+       (print_gnu_property_note): Add case for AArch64 gnu notes.
+
 2019-03-12  Alan Modra  <amodra@gmail.com>
 
        * objdump.c (load_specific_debug_section): Don't compare section
index 38e9f1b3455c0f92ff53b76630a1bb80ee08c8e2..7446ffeee21961bf56b12ff16afbf52e5cd35387 100644 (file)
@@ -17341,6 +17341,33 @@ decode_x86_feature_2 (unsigned int bitmask)
     }
 }
 
+static void
+decode_aarch64_feature_1_and (unsigned int bitmask)
+{
+  while (bitmask)
+    {
+      unsigned int bit = bitmask & (- bitmask);
+
+      bitmask &= ~ bit;
+      switch (bit)
+       {
+       case GNU_PROPERTY_AARCH64_FEATURE_1_BTI:
+         printf ("BTI");
+         break;
+
+       case GNU_PROPERTY_AARCH64_FEATURE_1_PAC:
+         printf ("PAC");
+         break;
+
+       default:
+         printf (_("<unknown: %x>"), bit);
+         break;
+       }
+      if (bitmask)
+       printf (", ");
+    }
+}
+
 static void
 print_gnu_property_note (Filedata * filedata, Elf_Internal_Note * pnote)
 {
@@ -17475,6 +17502,18 @@ print_gnu_property_note (Filedata * filedata, Elf_Internal_Note * pnote)
                  break;
                }
            }
+         else if (filedata->file_header.e_machine == EM_AARCH64)
+           {
+             if (type == GNU_PROPERTY_AARCH64_FEATURE_1_AND)
+               {
+                 printf ("AArch64 feature: ");
+                 if (datasz != 4)
+                   printf (_("<corrupt length: %#x> "), datasz);
+                 else
+                   decode_aarch64_feature_1_and (byte_get (ptr, 4));
+                 goto next;
+               }
+           }
        }
       else
        {
index 6d6ec66b18fd84d5326d5b99d23c60729af581cc..cf4353c9f500d6c9f6024a2ae3c82e32c5e064a9 100644 (file)
@@ -1,3 +1,9 @@
+2019-03-13  Sudakshina Das  <sudi.das@arm.com>
+
+       * elf/common.h (GNU_PROPERTY_AARCH64_FEATURE_1_AND): New.
+       (GNU_PROPERTY_AARCH64_FEATURE_1_BTI): New.
+       (GNU_PROPERTY_AARCH64_FEATURE_1_PAC): New.
+
 2019-02-20  Alan Hayward  <alan.hayward@arm.com>
 
        * elf/common.h (NT_ARM_PAC_MASK): Add define.
index e8faf67be3707f60c1f9a178ed4730551238835b..ebdb8212d118ed02132b8f94f26b628c1e1f681d 100644 (file)
 #define GNU_PROPERTY_X86_FEATURE_2_XSAVEOPT    (1U << 8)
 #define GNU_PROPERTY_X86_FEATURE_2_XSAVEC      (1U << 9)
 
+/* AArch64 specific GNU PROPERTY.  */
+#define GNU_PROPERTY_AARCH64_FEATURE_1_AND     0xc0000000
+
+#define GNU_PROPERTY_AARCH64_FEATURE_1_BTI     (1U << 0)
+#define GNU_PROPERTY_AARCH64_FEATURE_1_PAC     (1U << 1)
+
 /* Values used in GNU .note.ABI-tag notes (NT_GNU_ABI_TAG).  */
 #define GNU_ABI_TAG_LINUX      0
 #define GNU_ABI_TAG_HURD       1
index 3722d4f53e4312a9bd6263571ff7f9e69007fe32..32b53878508de1fd195ce2a02d4b6525afdaff41 100644 (file)
@@ -1,3 +1,14 @@
+2019-03-13  Sudakshina Das  <sudi.das@arm.com>
+
+       * NEWS: Document GNU_PROPERTY_AARCH64_FEATURE_1_BTI and
+       GNU_PROPERTY_AARCH64_FEATURE_1_PAC.
+       * testsuite/ld-aarch64/aarch64-elf.exp: Add run commands for new tests.
+       * testsuite/ld-aarch64/property-bti-pac1.d: New test.
+       * testsuite/ld-aarch64/property-bti-pac1.s: New test.
+       * testsuite/ld-aarch64/property-bti-pac2.d: New test.
+       * testsuite/ld-aarch64/property-bti-pac2.s: New test.
+       * testsuite/ld-aarch64/property-bti-pac3.d: New test.
+
 2019-03-13  H.J. Lu  <hongjiu.lu@intel.com>
 
        PR ld/24322
diff --git a/ld/NEWS b/ld/NEWS
index d737af70516547ecb4723a7e316493408d920353..dcf11854f528028820cbe1983bbcdd5753d97eaf 100644 (file)
--- a/ld/NEWS
+++ b/ld/NEWS
@@ -1,5 +1,15 @@
 -*- text -*-
 
+Changes in 2.33:
+
+* Add target handlers for AArch64 for ELF GNU program properties.
+
+* Add support for GNU_PROPERTY_AARCH64_FEATURE_1_BTI in ELF GNU program
+  properties in the AArch64 ELF linker.
+
+* Add support for GNU_PROPERTY_AARCH64_FEATURE_1_PAC in ELF GNU program
+  properties in the AArch64 ELF linker.
+
 Changes in 2.32:
 
 * Report property change in linker map file when merging GNU properties.
index 2b9fad5604b64d44e0fe48aa471bc726d9ce4332..c6fefbbd5c3f7e5516086c7eca0e056ae243d36d 100644 (file)
@@ -371,6 +371,10 @@ run_dump_test_lp64 "rela-abs-relative-opt"
 
 run_dump_test_lp64 "pie-bind-locally"
 
+run_dump_test "property-bti-pac1"
+run_dump_test "property-bti-pac2"
+run_dump_test "property-bti-pac3"
+
 set aarch64elflinktests {
   {"ld-aarch64/so with global symbol" "-shared" "" "" {copy-reloc-so.s}
     {} "copy-reloc-so.so"}
diff --git a/ld/testsuite/ld-aarch64/property-bti-pac1.d b/ld/testsuite/ld-aarch64/property-bti-pac1.d
new file mode 100644 (file)
index 0000000..a681ad9
--- /dev/null
@@ -0,0 +1,11 @@
+#name: GNU Property (single input, combine section)
+#source: property-bti-pac1.s
+#as: -march=armv8.5-a -defsym __mult__=0
+#ld: -shared
+#readelf: -n
+#target: *linux*
+
+Displaying notes found in: .note.gnu.property
+  Owner                 Data size      Description
+  GNU                  0x00000010      NT_GNU_PROPERTY_TYPE_0
+      Properties: AArch64 feature: BTI, PAC
diff --git a/ld/testsuite/ld-aarch64/property-bti-pac1.s b/ld/testsuite/ld-aarch64/property-bti-pac1.s
new file mode 100644 (file)
index 0000000..414c927
--- /dev/null
@@ -0,0 +1,37 @@
+       .text
+       .globl _start
+       .type _start,@function
+_start:
+       mov x1, #2
+.ifndef __mult__
+       bl foo
+.endif
+       .section ".note.gnu.property", "a"
+       .p2align 3
+       .long 1f - 0f           /* name length */
+       .long 5f - 2f           /* data length */
+       .long 5                 /* note type */
+0:     .asciz "GNU"            /* vendor name */
+1:
+       .p2align 3
+2:     .long 0xc0000000        /* pr_type.  */
+       .long 4f - 3f           /* pr_datasz.  */
+3:
+       .long 0x2               /* PAC.  */
+4:
+       .p2align 3
+5:
+       .p2align 3
+       .long 1f - 0f           /* name length */
+       .long 5f - 2f           /* data length */
+       .long 5                 /* note type */
+0:     .asciz "GNU"            /* vendor name */
+1:
+       .p2align 3
+2:     .long 0xc0000000        /* pr_type.  */
+       .long 4f - 3f           /* pr_datasz.  */
+3:
+       .long 0x1               /* BTI.  */
+4:
+       .p2align 3
+5:
diff --git a/ld/testsuite/ld-aarch64/property-bti-pac2.d b/ld/testsuite/ld-aarch64/property-bti-pac2.d
new file mode 100644 (file)
index 0000000..bc2eaad
--- /dev/null
@@ -0,0 +1,12 @@
+#name: GNU Property (combine multiple with BTI)
+#source: property-bti-pac1.s
+#source: property-bti-pac2.s
+#as: -mabi=lp64 -defsym __property_bti__=1
+#ld: -e _start
+#readelf: -n
+#target: *linux*
+
+Displaying notes found in: .note.gnu.property
+  Owner                 Data size      Description
+  GNU                  0x00000010      NT_GNU_PROPERTY_TYPE_0
+      Properties: AArch64 feature: BTI
diff --git a/ld/testsuite/ld-aarch64/property-bti-pac2.s b/ld/testsuite/ld-aarch64/property-bti-pac2.s
new file mode 100644 (file)
index 0000000..cdec8d9
--- /dev/null
@@ -0,0 +1,50 @@
+       .text
+       .global foo
+       .type   foo, %function
+foo:
+       sub     sp, sp, #16
+       mov     w0, 9
+       str     w0, [sp, 12]
+       ldr     w0, [sp, 12]
+       add     w0, w0, 4
+       str     w0, [sp, 12]
+       nop
+       add     sp, sp, 16
+       ret
+       .size   foo, .-foo
+       .global bar
+       .type   bar, %function
+.ifdef __property_bti__
+       .section ".note.gnu.property", "a"
+       .p2align 3
+       .long 1f - 0f           /* name length */
+       .long 5f - 2f           /* data length */
+       .long 5                 /* note type */
+0:     .asciz "GNU"            /* vendor name */
+1:
+       .p2align 3
+2:     .long 0xc0000000        /* pr_type.  */
+       .long 4f - 3f           /* pr_datasz.  */
+3:
+       .long 0x1               /* BTI.  */
+4:
+       .p2align 3
+5:
+.endif
+.ifdef __property_pac__
+       .section ".note.gnu.property", "a"
+       .p2align 3
+       .long 1f - 0f           /* name length */
+       .long 5f - 2f           /* data length */
+       .long 5                 /* note type */
+0:     .asciz "GNU"            /* vendor name */
+1:
+       .p2align 3
+2:     .long 0xc0000000        /* pr_type.  */
+       .long 4f - 3f           /* pr_datasz.  */
+3:
+       .long 0x2               /* PAC.  */
+4:
+       .p2align 3
+5:
+.endif
diff --git a/ld/testsuite/ld-aarch64/property-bti-pac3.d b/ld/testsuite/ld-aarch64/property-bti-pac3.d
new file mode 100644 (file)
index 0000000..5290f4b
--- /dev/null
@@ -0,0 +1,12 @@
+#name: GNU Property (combine multiple with PAC)
+#source: property-bti-pac1.s
+#source: property-bti-pac2.s
+#as: -mabi=lp64 -defsym __property_pac__=1
+#ld: -e _start
+#readelf: -n
+#target: *linux*
+
+Displaying notes found in: .note.gnu.property
+  Owner                 Data size      Description
+  GNU                  0x00000010      NT_GNU_PROPERTY_TYPE_0
+      Properties: AArch64 feature: PAC