public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [PATCH, BFD, LD, AArch64, 0/4] Add support for AArch64 BTI and PAC in the linker
@ 2019-03-06 10:26 Sudakshina Das
  2019-03-06 10:31 ` [PATCH, BFD, LD, AArch64, 1/4] Add support for GNU PROPERTIES in AArch64 for BTI and PAC Sudakshina Das
  2019-03-07 12:37 ` [PATCH, BFD, LD, AArch64, 0/4] Add support for AArch64 BTI and PAC in the linker Nick Clifton
  0 siblings, 2 replies; 22+ messages in thread
From: Sudakshina Das @ 2019-03-06 10:26 UTC (permalink / raw)
  To: binutils; +Cc: nd, nickc, Richard Earnshaw, Ramana Radhakrishnan

Hi

This patch series is aimed at giving support for the new Armv8.3-A 
Pointer Authentication and Armv8.5-A Branch Target Identification 
feature in the linker.

In order to support these, we propose to make the following changes:
1) We have defined .note.gnu.property for AArch64.
2) We have defined a new Program Property type
GNU_PROPERTY_AARCH64_FEATURE_1_AND and used 2 bits to represent
BTI and PAC respectively.
   - GNU_PROPERTY_AARCH64_FEATURE_1_BTI
   - GNU_PROPERTY_AARCH64_FEATURE_1_PAC (We have only reserved this bit
     for now.)
3) We also need custom PLTs when these features are turned on and thus
we have defined the following processor-specific dynamic array tags:
   - DT_AARCH64_BTI_PLT
   - DT_AARCH64_PAC_PLT
Details of these can be found in the new AArch64 ELF documentation:
https://developer.arm.com/docs/ihi0056/latest/elf-for-the-arm-64-bit-architecture-aarch64-abi-2018q4

Command line options:
We introduce a new set of command line options for the linker in order 
to support the correct PLTs
1) --pac-plt : In the presence of this option, the linker uses a PAC 
enabled PLT. It also uses the dynamic tag DT_AARCH64_PAC_PLT to reflect 
the same. Other tools like Objdump can use this to determine the size of 
the PLTs.
2) --bti: In the presence of this option, the linker enables BTI with 
the GNU_PROPERTY_AARCH64_FEATURE_1_BTI feature and also uses a BTI 
enabled PLT. It also uses the dynamic tag DT_AARCH64_BTI_PLT to reflect 
the choice of the PLTs. Other tools like Objdump can use this to 
determine the size of the PLTs. Using this option can give a warning if 
not all input objects are marked with GNU_PROPERTY_AARCH64_FEATURE_1_BTI.
3)--bti-nowarn - Same as above but does not emit any warnings.

In terms of the PLTs, in the presence of both --pac-plt and 
--bti/--bti-nowarn, the linker chooses the PLTs protected with both BTI 
and PAC and uses both DT_AARCH64_PAC_PLT and DT_AARCH64_BTI_PLT.

Interaction between Command line arguments and GNU NOTE section
1) For PAC, in the presence of --pac-plt along with BIND_NOW, the linker 
can choose to ignore the pac-plt directive and use smaller PLTs without 
compromising on security,
2) For BTI, the linker must also check for the 
GNU_PROPERTY_AARCH64_FEATURE_1_BTI in its input. If all inputs have 
GNU_PROPERTY_AARCH64_FEATURE_1_BTI, the final output will also be marked 
as such. The PLT should also be protected with a BTI PLT in this case. 
Thus even if there is no linker option to use BTI PLT, the linker
should be able to use them depending on the NOTE section. The user can 
use the linker option --bti, to make sure that their intention of having 
all input objects (and hence the output) marked with BTI is not 
disrupted by any stray objects as this option will warn about it.


The following patches implement these changes as follows:
[1/4] Add support for GNU PROPERTIES in AArch64 for BTI and PAC:
[2/4] Add --bti-nowarn to enable BTI without warning and to select BTI 
enabled PLTs
[3/4] Add --bti to enable BTI and select BTI enabled PLTs but also warn 
for missing NOTE sections.
[4/4] Add --pac-plt to enable PLTs protected with PAC.

This is my first time making such intrusive changes to the linker. 
Please be kind :P

Thanks
Sudi

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

* [PATCH, BFD, LD, AArch64, 1/4] Add support for GNU PROPERTIES in AArch64 for BTI and PAC
  2019-03-06 10:26 [PATCH, BFD, LD, AArch64, 0/4] Add support for AArch64 BTI and PAC in the linker Sudakshina Das
@ 2019-03-06 10:31 ` Sudakshina Das
  2019-03-06 10:34   ` [PATCH, BFD, LD, AArch64, 2/4] Add --bti-nowarn to enable BTI without warning and to select BTI enabled PLTs Sudakshina Das
  2019-03-07 12:37 ` [PATCH, BFD, LD, AArch64, 0/4] Add support for AArch64 BTI and PAC in the linker Nick Clifton
  1 sibling, 1 reply; 22+ messages in thread
From: Sudakshina Das @ 2019-03-06 10:31 UTC (permalink / raw)
  To: binutils; +Cc: nd, nickc, Ramana Radhakrishnan

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

Hi

On 06/03/2019 10:26, Sudakshina Das wrote:
> Hi
> 
> This patch series is aimed at giving support for the new Armv8.3-A 
> Pointer Authentication and Armv8.5-A Branch Target Identification 
> feature in the linker.
> 
> In order to support these, we propose to make the following changes:
> 1) We have defined .note.gnu.property for AArch64.
> 2) We have defined a new Program Property type
> GNU_PROPERTY_AARCH64_FEATURE_1_AND and used 2 bits to represent
> BTI and PAC respectively.
>    - GNU_PROPERTY_AARCH64_FEATURE_1_BTI
>    - GNU_PROPERTY_AARCH64_FEATURE_1_PAC (We have only reserved this bit
>      for now.)
> 3) We also need custom PLTs when these features are turned on and thus
> we have defined the following processor-specific dynamic array tags:
>    - DT_AARCH64_BTI_PLT
>    - DT_AARCH64_PAC_PLT
> Details of these can be found in the new AArch64 ELF documentation:
> https://developer.arm.com/docs/ihi0056/latest/elf-for-the-arm-64-bit-architecture-aarch64-abi-2018q4 
> 
> 
> Command line options:
> We introduce a new set of command line options for the linker in order 
> to support the correct PLTs
> 1) --pac-plt : In the presence of this option, the linker uses a PAC 
> enabled PLT. It also uses the dynamic tag DT_AARCH64_PAC_PLT to reflect 
> the same. Other tools like Objdump can use this to determine the size of 
> the PLTs.
> 2) --bti: In the presence of this option, the linker enables BTI with 
> the GNU_PROPERTY_AARCH64_FEATURE_1_BTI feature and also uses a BTI 
> enabled PLT. It also uses the dynamic tag DT_AARCH64_BTI_PLT to reflect 
> the choice of the PLTs. Other tools like Objdump can use this to 
> determine the size of the PLTs. Using this option can give a warning if 
> not all input objects are marked with GNU_PROPERTY_AARCH64_FEATURE_1_BTI.
> 3)--bti-nowarn - Same as above but does not emit any warnings.
> 
> In terms of the PLTs, in the presence of both --pac-plt and 
> --bti/--bti-nowarn, the linker chooses the PLTs protected with both BTI 
> and PAC and uses both DT_AARCH64_PAC_PLT and DT_AARCH64_BTI_PLT.
> 
> Interaction between Command line arguments and GNU NOTE section
> 1) For PAC, in the presence of --pac-plt along with BIND_NOW, the linker 
> can choose to ignore the pac-plt directive and use smaller PLTs without 
> compromising on security,
> 2) For BTI, the linker must also check for the 
> GNU_PROPERTY_AARCH64_FEATURE_1_BTI in its input. If all inputs have 
> GNU_PROPERTY_AARCH64_FEATURE_1_BTI, the final output will also be marked 
> as such. The PLT should also be protected with a BTI PLT in this case. 
> Thus even if there is no linker option to use BTI PLT, the linker
> should be able to use them depending on the NOTE section. The user can 
> use the linker option --bti, to make sure that their intention of having 
> all input objects (and hence the output) marked with BTI is not 
> disrupted by any stray objects as this option will warn about it.
> 
> 
> The following patches implement these changes as follows:
> [1/4] Add support for GNU PROPERTIES in AArch64 for BTI and PAC:
> [2/4] Add --bti-nowarn to enable BTI without warning and to select BTI 
> enabled PLTs
> [3/4] Add --bti to enable BTI and select BTI enabled PLTs but also warn 
> for missing NOTE sections.
> [4/4] Add --pac-plt to enable PLTs protected with PAC.
> 
> This is my first time making such intrusive changes to the linker. 
> Please be kind :P
> 
> Thanks
> Sudi

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

Build and regression tests all pass on aarch64-none-linux-gnu and
new tests are added.

Is this ok for trunk?

Thanks
Sudi

*** bfd/ChangeLog ***

2019-xx-xx  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-xx-xx  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-xx-xx  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-xx-xx  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.

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: rb10053.patch --]
[-- Type: text/x-patch; name="rb10053.patch", Size: 17221 bytes --]

diff --git a/bfd/elf-properties.c b/bfd/elf-properties.c
index 5e48d75faa2694538cbbb74af0a86bfe85da3fd3..0c3f19ce56a36bb18d9afd2e140d735eeaf9c6a9 100644
--- a/bfd/elf-properties.c
+++ b/bfd/elf-properties.c
@@ -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;
diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c
index faa27611d466ce75e5c02d8bbcfca6459618d4bd..5b8cc4c9701feacd0deb5c998c89d17d97864646 100644
--- a/bfd/elfnn-aarch64.c
+++ b/bfd/elfnn-aarch64.c
@@ -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
diff --git a/bfd/elfxx-aarch64.h b/bfd/elfxx-aarch64.h
index 1f9ce09675f5e21da4ddff5a1e72d75552110c3f..a6d1792687cf39a68beb3235f5875d50bfc3ad4e 100644
--- a/bfd/elfxx-aarch64.h
+++ b/bfd/elfxx-aarch64.h
@@ -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
diff --git a/bfd/elfxx-aarch64.c b/bfd/elfxx-aarch64.c
index 32a9d972824d653785358f933a1157533f6e9779..cae94d03e8453de0cceee1619668fff71a609edf 100644
--- a/bfd/elfxx-aarch64.c
+++ b/bfd/elfxx-aarch64.c
@@ -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;
+}
diff --git a/binutils/readelf.c b/binutils/readelf.c
index 38e9f1b3455c0f92ff53b76630a1bb80ee08c8e2..7446ffeee21961bf56b12ff16afbf52e5cd35387 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -17342,6 +17342,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)
 {
   unsigned char * ptr = (unsigned char *) pnote->descdata;
@@ -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
 	{
diff --git a/include/elf/common.h b/include/elf/common.h
index e8faf67be3707f60c1f9a178ed4730551238835b..ebdb8212d118ed02132b8f94f26b628c1e1f681d 100644
--- a/include/elf/common.h
+++ b/include/elf/common.h
@@ -841,6 +841,12 @@
 #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
diff --git a/ld/NEWS b/ld/NEWS
index d737af70516547ecb4723a7e316493408d920353..dcf11854f528028820cbe1983bbcdd5753d97eaf 100644
--- 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.
diff --git a/ld/testsuite/ld-aarch64/aarch64-elf.exp b/ld/testsuite/ld-aarch64/aarch64-elf.exp
index 2b9fad5604b64d44e0fe48aa471bc726d9ce4332..c6fefbbd5c3f7e5516086c7eca0e056ae243d36d 100644
--- a/ld/testsuite/ld-aarch64/aarch64-elf.exp
+++ b/ld/testsuite/ld-aarch64/aarch64-elf.exp
@@ -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
index 0000000000000000000000000000000000000000..a681ad94f885506da7831230a93e26eecb800c8a
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/property-bti-pac1.d
@@ -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
index 0000000000000000000000000000000000000000..414c9277f1dabc5fdc08b8b71716c44ea8bc8343
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/property-bti-pac1.s
@@ -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
index 0000000000000000000000000000000000000000..bc2eaada9ecdb952efd1c9c57d715773ed216852
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/property-bti-pac2.d
@@ -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
index 0000000000000000000000000000000000000000..cdec8d998724e67bcc778bba77eac7bf85c05626
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/property-bti-pac2.s
@@ -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
index 0000000000000000000000000000000000000000..5290f4bd8110d127e19712ce8891bb54bdfbc352
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/property-bti-pac3.d
@@ -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

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

* [PATCH, BFD, LD, AArch64, 2/4] Add --bti-nowarn to enable BTI without warning and to select BTI enabled PLTs
  2019-03-06 10:31 ` [PATCH, BFD, LD, AArch64, 1/4] Add support for GNU PROPERTIES in AArch64 for BTI and PAC Sudakshina Das
@ 2019-03-06 10:34   ` Sudakshina Das
  2019-03-06 10:36     ` [PATCH, BFD, LD, AArch64, 3/4] Add --bti to enable BTI and select BTI enabled PLTs but also warn for missing NOTE sections Sudakshina Das
  0 siblings, 1 reply; 22+ messages in thread
From: Sudakshina Das @ 2019-03-06 10:34 UTC (permalink / raw)
  To: binutils; +Cc: nd, nickc, Ramana Radhakrishnan

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

Hi

On 06/03/2019 10:30, Sudakshina Das wrote:
> Hi
> 
> On 06/03/2019 10:26, Sudakshina Das wrote:
>> Hi
>>
>> This patch series is aimed at giving support for the new Armv8.3-A 
>> Pointer Authentication and Armv8.5-A Branch Target Identification 
>> feature in the linker.
>>
>> In order to support these, we propose to make the following changes:
>> 1) We have defined .note.gnu.property for AArch64.
>> 2) We have defined a new Program Property type
>> GNU_PROPERTY_AARCH64_FEATURE_1_AND and used 2 bits to represent
>> BTI and PAC respectively.
>>    - GNU_PROPERTY_AARCH64_FEATURE_1_BTI
>>    - GNU_PROPERTY_AARCH64_FEATURE_1_PAC (We have only reserved this bit
>>      for now.)
>> 3) We also need custom PLTs when these features are turned on and thus
>> we have defined the following processor-specific dynamic array tags:
>>    - DT_AARCH64_BTI_PLT
>>    - DT_AARCH64_PAC_PLT
>> Details of these can be found in the new AArch64 ELF documentation:
>> https://developer.arm.com/docs/ihi0056/latest/elf-for-the-arm-64-bit-architecture-aarch64-abi-2018q4 
>>
>>
>> Command line options:
>> We introduce a new set of command line options for the linker in order 
>> to support the correct PLTs
>> 1) --pac-plt : In the presence of this option, the linker uses a PAC 
>> enabled PLT. It also uses the dynamic tag DT_AARCH64_PAC_PLT to 
>> reflect the same. Other tools like Objdump can use this to determine 
>> the size of the PLTs.
>> 2) --bti: In the presence of this option, the linker enables BTI with 
>> the GNU_PROPERTY_AARCH64_FEATURE_1_BTI feature and also uses a BTI 
>> enabled PLT. It also uses the dynamic tag DT_AARCH64_BTI_PLT to 
>> reflect the choice of the PLTs. Other tools like Objdump can use this 
>> to determine the size of the PLTs. Using this option can give a 
>> warning if not all input objects are marked with 
>> GNU_PROPERTY_AARCH64_FEATURE_1_BTI.
>> 3)--bti-nowarn - Same as above but does not emit any warnings.
>>
>> In terms of the PLTs, in the presence of both --pac-plt and 
>> --bti/--bti-nowarn, the linker chooses the PLTs protected with both 
>> BTI and PAC and uses both DT_AARCH64_PAC_PLT and DT_AARCH64_BTI_PLT.
>>
>> Interaction between Command line arguments and GNU NOTE section
>> 1) For PAC, in the presence of --pac-plt along with BIND_NOW, the 
>> linker can choose to ignore the pac-plt directive and use smaller PLTs 
>> without compromising on security,
>> 2) For BTI, the linker must also check for the 
>> GNU_PROPERTY_AARCH64_FEATURE_1_BTI in its input. If all inputs have 
>> GNU_PROPERTY_AARCH64_FEATURE_1_BTI, the final output will also be 
>> marked as such. The PLT should also be protected with a BTI PLT in 
>> this case. Thus even if there is no linker option to use BTI PLT, the 
>> linker
>> should be able to use them depending on the NOTE section. The user can 
>> use the linker option --bti, to make sure that their intention of 
>> having all input objects (and hence the output) marked with BTI is not 
>> disrupted by any stray objects as this option will warn about it.
>>
>>
>> The following patches implement these changes as follows:
>> [1/4] Add support for GNU PROPERTIES in AArch64 for BTI and PAC:
>> [2/4] Add --bti-nowarn to enable BTI without warning and to select BTI 
>> enabled PLTs
>> [3/4] Add --bti to enable BTI and select BTI enabled PLTs but also 
>> warn for missing NOTE sections.
>> [4/4] Add --pac-plt to enable PLTs protected with PAC.
>>
>> This is my first time making such intrusive changes to the linker. 
>> Please be kind :P
>>
>> Thanks
>> Sudi
> 
> 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 
> 
> 
> Build and regression tests all pass on aarch64-none-linux-gnu and
> new tests are added.
> 
> Is this ok for trunk?
> 
> Thanks
> Sudi
> 
> *** bfd/ChangeLog ***
> 
> 2019-xx-xx  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-xx-xx  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-xx-xx  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-xx-xx  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.

This is part of the patch series to add support for BTI and
PAC in AArch64 linker.

1) This patch adds a new ld command line option: --bti-nowarn.
In the presence of this option, the linker enables BTI with the
GNU_PROPERTY_AARCH64_FEATURE_1_BTI feature. This gives no warning
in case of missing gnu notes for BTI in inputs.
2) It also defines a new set of BTI enabled PLTs. These are used either
when all the inputs are marked with GNU_PROPERTY_AARCH64_FEATURE_1_BTI
or when the new --bti-nowarn option is used. This required adding new
fields in elf_aarch64_link_hash_table so that we could make the PLT
related information more generic.
3) It also defines a dynamic tag DT_AARCH64_BTI_PLT. The linker uses
this whenever it picks BTI enabled PLTs.
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

Build and regression tests all pass on aarch64-none-linux-gnu and
new tests are added.

Is this ok for trunk?

Thanks
Sudi

*** bfd/ChangeLog ***

2019-xx-xx  Sudakshina Das  <sudi.das@arm.com>
	    Szabolcs Nagy  <szabolcs.nagy@arm.com>

	* bfd-in.h (aarch64_plt_type, aarch64_enable_bti_type): New.
	(aarch64_bti_pac_info): New.
	(bfd_elf64_aarch64_set_options): Add aarch64_bti_pac_info argument.
	(bfd_elf32_aarch64_set_options): Likewise.
	* bfd-in2.h: Regenerate
	* elfnn-aarch64.c (PLT_BTI_ENTRY_SIZE): New.
	(PLT_BTI_SMALL_ENTRY_SIZE, PLT_BTI_TLSDESC_ENTRY_SIZE): New.
	(elfNN_aarch64_small_plt0_bti_entry): New.
	(elfNN_aarch64_small_plt_bti_entry): New.
	(elfNN_aarch64_tlsdesc_small_plt_bti_entry): New.
	(elf_aarch64_obj_tdata): Add no_enable_bti_warn and plt_type fields.
	(elf_aarch64_link_hash_table): Add plt0_entry, plt_entry and
	tlsdesc_plt_entry_size fields.
	(elfNN_aarch64_link_hash_table_create): Initialise the new fields.
	(setup_plt_values): New helper function.
	(bfd_elfNN_aarch64_set_options): Use new bp_info to set plt sizes and
	bti enable type.
	(elfNN_aarch64_allocate_dynrelocs): Use new size members instead of
	fixed macros.
	(elfNN_aarch64_size_dynamic_sections): Likewise and add checks.
	(elfNN_aarch64_create_small_pltn_entry): Use new generic pointers
	to plt stubs instead of fixed ones and update filling them according
	to the need for bti.
	(elfNN_aarch64_init_small_plt0_entry): Likewise.
	(elfNN_aarch64_finish_dynamic_sections): Likewise.
	(get_plt_type, elfNN_aarch64_get_synthetic_symtab): New.
	(elfNN_aarch64_plt_sym_val): Update size accordingly.
	(elfNN_aarch64_link_setup_gnu_properties): Set up plts if BTI GNU NOTE
	is set.
	(bfd_elfNN_get_synthetic_symtab): Define.

*** binutils/ChangeLog ***

2019-xx-xx  Sudakshina Das  <sudi.das@arm.com>
	    Szabolcs Nagy  <szabolcs.nagy@arm.com>

	* readelf.c (get_aarch64_dynamic_type): New.
	(get_dynamic_type): Use above for EM_AARCH64.
	(dynamic_section_aarch64_val): New.
	(process_dynamic_section): Use above for EM_AARCH64.

*** include/ChangeLog ***

2019-xx-xx  Sudakshina Das  <sudi.das@arm.com>
	    Szabolcs Nagy  <szabolcs.nagy@arm.com>

	* elf/aarch64.h (DT_AARCH64_BTI_PLT): New.

*** ld/ChangeLog ***

2019-xx-xx  Sudakshina Das  <sudi.das@arm.com>
	    Szabolcs Nagy  <szabolcs.nagy@arm.com>

	* NEWS: Document --bti-nowarn.
	* emultempl/aarch64elf.em (plt_type, bti_type, OPTION_BTI_NOWARN): New.
	(PARSE_AND_LIST_SHORTOPTS, PARSE_AND_LIST_OPTIONS): Add bti-nowarn.
	(PARSE_AND_LIST_ARGS_CASES): Handle OPTION_BTI_NOWARN.
	* testsuite/ld-aarch64/aarch64-elf.exp: Add all the tests below.
	* testsuite/ld-aarch64/bti-plt-1.d: New test.
	* testsuite/ld-aarch64/bti-plt-1.s: New test.
	* testsuite/ld-aarch64/bti-plt-2.d: New test.
	* testsuite/ld-aarch64/bti-plt-3.d: New test.
	* testsuite/ld-aarch64/bti-plt-4.d: New test.
	* testsuite/ld-aarch64/bti-plt-5.d: New test.
	* testsuite/ld-aarch64/bti-plt-so.s: New test.
	* testsuite/ld-aarch64/bti-plt.ld: New test.

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: rb10138.patch --]
[-- Type: text/x-patch; name="rb10138.patch", Size: 32524 bytes --]

diff --git a/bfd/bfd-in.h b/bfd/bfd-in.h
index e7c2eaa93591ca2fc2cfd6f2c5a161ba0c2928a1..61affcbbb991e4c5b6c5ca28df0c60eafec3da05 100644
--- a/bfd/bfd-in.h
+++ b/bfd/bfd-in.h
@@ -995,11 +995,46 @@ extern void bfd_elf64_aarch64_init_maps
 extern void bfd_elf32_aarch64_init_maps
   (bfd *);
 
+/* Types of PLTs based on the level of security.  This would be a
+   bit-mask to denote which of the combinations of security features
+   are enabled:
+   - No security feature PLTs
+   - PLTs with BTI instruction
+   - PLTs with PAC instruction
+*/
+typedef enum
+{
+  PLT_NORMAL	= 0x0,  /* Normal plts.  */
+  PLT_BTI	= 0x1,  /* plts with bti.  */
+  PLT_PAC	= 0x2,  /* plts with pointer authentication.  */
+  PLT_BTI_PAC	= PLT_BTI | PLT_PAC
+} aarch64_plt_type;
+
+/* To indicate if BTI is enabled with/without warning.  */
+typedef enum
+{
+  BTI_NONE	= 0,  /* BTI is not enabled.  */
+  BTI_NOWARN	= 1,  /* BTI is enabled with --bti-nowarn.  */
+  BTI_WARN	= 2,  /* BTI is enabled with --bti.  */
+} aarch64_enable_bti_type;
+
+/* A structure to encompass all information coming from BTI or PAC
+   related command line options.  This involves the "PLT_TYPE" to determine
+   which version of PLTs to pick and "BTI_TYPE" to determine if
+   BTI should be turned on with/without any warnings.   */
+typedef struct
+{
+  aarch64_plt_type plt_type;
+  aarch64_enable_bti_type bti_type;
+} aarch64_bti_pac_info;
+
 extern void bfd_elf64_aarch64_set_options
-  (bfd *, struct bfd_link_info *, int, int, int, int, int, int);
+  (bfd *, struct bfd_link_info *, int, int, int, int, int, int,
+   aarch64_bti_pac_info);
 
 extern void bfd_elf32_aarch64_set_options
-  (bfd *, struct bfd_link_info *, int, int, int, int, int, int);
+  (bfd *, struct bfd_link_info *, int, int, int, int, int, int,
+   aarch64_bti_pac_info);
 
 /* ELF AArch64 mapping symbol support.  */
 #define BFD_AARCH64_SPECIAL_SYM_TYPE_MAP	(1 << 0)
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index e25da50aafbf4fe14b7220bb2d0791ac7899b4f6..5bc09f50c4d68dba7615007dccdc9b541e49aa04 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -1002,11 +1002,46 @@ extern void bfd_elf64_aarch64_init_maps
 extern void bfd_elf32_aarch64_init_maps
   (bfd *);
 
+/* Types of PLTs based on the level of security.  This would be a
+   bit-mask to denote which of the combinations of security features
+   are enabled:
+   - No security feature PLTs
+   - PLTs with BTI instruction
+   - PLTs with PAC instruction
+*/
+typedef enum
+{
+  PLT_NORMAL	= 0x0,  /* Normal plts.  */
+  PLT_BTI	= 0x1,  /* plts with bti.  */
+  PLT_PAC	= 0x2,  /* plts with pointer authentication.  */
+  PLT_BTI_PAC	= PLT_BTI | PLT_PAC
+} aarch64_plt_type;
+
+/* To indicate if BTI is enabled with/without warning.  */
+typedef enum
+{
+  BTI_NONE	= 0,  /* BTI is not enabled.  */
+  BTI_NOWARN	= 1,  /* BTI is enabled with --bti-nowarn.  */
+  BTI_WARN	= 2,  /* BTI is enabled with --bti.  */
+} aarch64_enable_bti_type;
+
+/* A structure to encompass all information coming from BTI or PAC
+   related command line options.  This involves the "PLT_TYPE" to determine
+   which version of PLTs to pick and "BTI_TYPE" to determine if
+   BTI should be turned on with/without any warnings.   */
+typedef struct
+{
+  aarch64_plt_type plt_type;
+  aarch64_enable_bti_type bti_type;
+} aarch64_bti_pac_info;
+
 extern void bfd_elf64_aarch64_set_options
-  (bfd *, struct bfd_link_info *, int, int, int, int, int, int);
+  (bfd *, struct bfd_link_info *, int, int, int, int, int, int,
+   aarch64_bti_pac_info);
 
 extern void bfd_elf32_aarch64_set_options
-  (bfd *, struct bfd_link_info *, int, int, int, int, int, int);
+  (bfd *, struct bfd_link_info *, int, int, int, int, int, int,
+   aarch64_bti_pac_info);
 
 /* ELF AArch64 mapping symbol support.  */
 #define BFD_AARCH64_SPECIAL_SYM_TYPE_MAP	(1 << 0)
diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c
index 5b8cc4c9701feacd0deb5c998c89d17d97864646..66fe86bbac45f2de1bce43c68036ff18ffb989a8 100644
--- a/bfd/elfnn-aarch64.c
+++ b/bfd/elfnn-aarch64.c
@@ -267,6 +267,10 @@
 #define PLT_ENTRY_SIZE			(32)
 #define PLT_SMALL_ENTRY_SIZE		(16)
 #define PLT_TLSDESC_ENTRY_SIZE		(32)
+/* PLT sizes with BTI insn.  */
+#define PLT_BTI_ENTRY_SIZE		(36)
+#define PLT_BTI_SMALL_ENTRY_SIZE	(20)
+#define PLT_BTI_TLSDESC_ENTRY_SIZE	(36)
 
 /* Encoding of the nop instruction.  */
 #define INSN_NOP 0xd503201f
@@ -297,9 +301,27 @@ static const bfd_byte elfNN_aarch64_small_plt0_entry[PLT_ENTRY_SIZE] =
   0x1f, 0x20, 0x03, 0xd5,	/* nop */
 };
 
+static const bfd_byte elfNN_aarch64_small_plt0_bti_entry[PLT_BTI_ENTRY_SIZE] =
+{
+  0x5f, 0x24, 0x03, 0xd5,	/* bti c.  */
+  0xf0, 0x7b, 0xbf, 0xa9,	/* stp x16, x30, [sp, #-16]!  */
+  0x10, 0x00, 0x00, 0x90,	/* adrp x16, (GOT+16)  */
+#if ARCH_SIZE == 64
+  0x11, 0x0A, 0x40, 0xf9,	/* ldr x17, [x16, #PLT_GOT+0x10]  */
+  0x10, 0x42, 0x00, 0x91,	/* add x16, x16,#PLT_GOT+0x10   */
+#else
+  0x11, 0x0A, 0x40, 0xb9,	/* ldr w17, [x16, #PLT_GOT+0x8]  */
+  0x10, 0x22, 0x00, 0x11,	/* add w16, w16,#PLT_GOT+0x8   */
+#endif
+  0x20, 0x02, 0x1f, 0xd6,	/* br x17  */
+  0x1f, 0x20, 0x03, 0xd5,	/* nop */
+  0x1f, 0x20, 0x03, 0xd5,	/* nop */
+  0x1f, 0x20, 0x03, 0xd5,	/* nop */
+};
+
 /* Per function entry in a procedure linkage table looks like this
    if the distance between the PLTGOT and the PLT is < 4GB use
-   these PLT entries.  */
+   these PLT entries.  Use BTI versions of the PLTs when enabled.  */
 static const bfd_byte elfNN_aarch64_small_plt_entry[PLT_SMALL_ENTRY_SIZE] =
 {
   0x10, 0x00, 0x00, 0x90,	/* adrp x16, PLTGOT + n * 8  */
@@ -314,6 +336,21 @@ static const bfd_byte elfNN_aarch64_small_plt_entry[PLT_SMALL_ENTRY_SIZE] =
 };
 
 static const bfd_byte
+elfNN_aarch64_small_plt_bti_entry[PLT_BTI_SMALL_ENTRY_SIZE] =
+{
+  0x5f, 0x24, 0x03, 0xd5,	/* bti c.  */
+  0x10, 0x00, 0x00, 0x90,	/* adrp x16, PLTGOT + n * 8  */
+#if ARCH_SIZE == 64
+  0x11, 0x02, 0x40, 0xf9,	/* ldr x17, [x16, PLTGOT + n * 8] */
+  0x10, 0x02, 0x00, 0x91,	/* add x16, x16, :lo12:PLTGOT + n * 8  */
+#else
+  0x11, 0x02, 0x40, 0xb9,	/* ldr w17, [x16, PLTGOT + n * 4] */
+  0x10, 0x02, 0x00, 0x11,	/* add w16, w16, :lo12:PLTGOT + n * 4  */
+#endif
+  0x20, 0x02, 0x1f, 0xd6,	/* br x17.  */
+};
+
+static const bfd_byte
 elfNN_aarch64_tlsdesc_small_plt_entry[PLT_TLSDESC_ENTRY_SIZE] =
 {
   0xe2, 0x0f, 0xbf, 0xa9,	/* stp x2, x3, [sp, #-16]! */
@@ -331,6 +368,25 @@ elfNN_aarch64_tlsdesc_small_plt_entry[PLT_TLSDESC_ENTRY_SIZE] =
   0x1f, 0x20, 0x03, 0xd5,	/* nop */
 };
 
+static const bfd_byte
+elfNN_aarch64_tlsdesc_small_plt_bti_entry[PLT_BTI_TLSDESC_ENTRY_SIZE] =
+{
+  0x5f, 0x24, 0x03, 0xd5,	/* bti c.  */
+  0xe2, 0x0f, 0xbf, 0xa9,	/* stp x2, x3, [sp, #-16]! */
+  0x02, 0x00, 0x00, 0x90,	/* adrp x2, 0 */
+  0x03, 0x00, 0x00, 0x90,	/* adrp x3, 0 */
+#if ARCH_SIZE == 64
+  0x42, 0x00, 0x40, 0xf9,	/* ldr x2, [x2, #0] */
+  0x63, 0x00, 0x00, 0x91,	/* add x3, x3, 0 */
+#else
+  0x42, 0x00, 0x40, 0xb9,	/* ldr w2, [x2, #0] */
+  0x63, 0x00, 0x00, 0x11,	/* add w3, w3, 0 */
+#endif
+  0x40, 0x00, 0x1f, 0xd6,	/* br x2 */
+  0x1f, 0x20, 0x03, 0xd5,	/* nop */
+  0x1f, 0x20, 0x03, 0xd5,	/* nop */
+};
+
 #define elf_info_to_howto		elfNN_aarch64_info_to_howto
 #define elf_info_to_howto_rel		elfNN_aarch64_info_to_howto
 
@@ -2438,6 +2494,13 @@ struct elf_aarch64_obj_tdata
 
   /* All GNU_PROPERTY_AARCH64_FEATURE_1_AND properties.  */
   uint32_t gnu_and_prop;
+
+  /* Zero to warn when linking objects with incompatible
+     GNU_PROPERTY_AARCH64_FEATURE_1_BTI.  */
+  int no_enable_bti_warn;
+
+  /* PLT type based on security.  */
+  aarch64_plt_type plt_type;
 };
 
 #define elf_aarch64_tdata(bfd)				\
@@ -2543,9 +2606,15 @@ struct elf_aarch64_link_hash_table
   /* The number of bytes in the initial entry in the PLT.  */
   bfd_size_type plt_header_size;
 
-  /* The number of bytes in the subsequent PLT etries.  */
+  /* The bytes of the initial PLT entry.  */
+  const bfd_byte *plt0_entry;
+
+  /* The number of bytes in the subsequent PLT entries.  */
   bfd_size_type plt_entry_size;
 
+  /* The bytes of the subsequent PLT entry.  */
+  const bfd_byte *plt_entry;
+
   /* Small local sym cache.  */
   struct sym_cache sym_cache;
 
@@ -2588,6 +2657,9 @@ struct elf_aarch64_link_hash_table
      yet.  */
   bfd_vma tlsdesc_plt;
 
+  /* The number of bytes in the PLT enty for the TLS descriptor.  */
+  bfd_size_type tlsdesc_plt_entry_size;
+
   /* The GOT offset for the lazy trampoline.  Communicated to the
      loader via DT_TLSDESC_GOT.  The magic value (bfd_vma) -1
      indicates an offset is not allocated.  */
@@ -2831,7 +2903,10 @@ elfNN_aarch64_link_hash_table_create (bfd *abfd)
     }
 
   ret->plt_header_size = PLT_ENTRY_SIZE;
+  ret->plt0_entry = elfNN_aarch64_small_plt0_entry;
   ret->plt_entry_size = PLT_SMALL_ENTRY_SIZE;
+  ret->plt_entry = elfNN_aarch64_small_plt_entry;
+  ret->tlsdesc_plt_entry_size = PLT_TLSDESC_ENTRY_SIZE;
   ret->obfd = abfd;
   ret->dt_tlsdesc_got = (bfd_vma) - 1;
 
@@ -4599,6 +4674,28 @@ bfd_elfNN_aarch64_init_maps (bfd *abfd)
     }
 }
 
+static void
+setup_plt_values (struct bfd_link_info *link_info,
+		  aarch64_plt_type plt_type)
+{
+  struct elf_aarch64_link_hash_table *globals;
+  globals = elf_aarch64_hash_table (link_info);
+
+  if (plt_type == PLT_BTI)
+    {
+      globals->plt_header_size = PLT_BTI_ENTRY_SIZE;
+      globals->plt0_entry = elfNN_aarch64_small_plt0_bti_entry;
+      globals->tlsdesc_plt_entry_size = PLT_BTI_TLSDESC_ENTRY_SIZE;
+
+      /* Only in ET_EXEC we need PLTn with BTI.  */
+      if (bfd_link_pde (link_info))
+	{
+	  globals->plt_entry_size = PLT_BTI_SMALL_ENTRY_SIZE;
+	  globals->plt_entry = elfNN_aarch64_small_plt_bti_entry;
+	}
+    }
+}
+
 /* Set option values needed during linking.  */
 void
 bfd_elfNN_aarch64_set_options (struct bfd *output_bfd,
@@ -4607,7 +4704,8 @@ bfd_elfNN_aarch64_set_options (struct bfd *output_bfd,
 			       int no_wchar_warn, int pic_veneer,
 			       int fix_erratum_835769,
 			       int fix_erratum_843419,
-			       int no_apply_dynamic_relocs)
+			       int no_apply_dynamic_relocs,
+			       aarch64_bti_pac_info bp_info)
 {
   struct elf_aarch64_link_hash_table *globals;
 
@@ -4621,6 +4719,26 @@ bfd_elfNN_aarch64_set_options (struct bfd *output_bfd,
   BFD_ASSERT (is_aarch64_elf (output_bfd));
   elf_aarch64_tdata (output_bfd)->no_enum_size_warning = no_enum_warn;
   elf_aarch64_tdata (output_bfd)->no_wchar_size_warning = no_wchar_warn;
+
+  switch (bp_info.bti_type)
+    {
+    case BTI_NOWARN:
+      elf_aarch64_tdata (output_bfd)->no_enable_bti_warn = 1;
+      elf_aarch64_tdata (output_bfd)->gnu_and_prop
+	|= GNU_PROPERTY_AARCH64_FEATURE_1_BTI;
+      break;
+
+    case BTI_WARN:
+      elf_aarch64_tdata (output_bfd)->no_enable_bti_warn = 0;
+      elf_aarch64_tdata (output_bfd)->gnu_and_prop
+	|= GNU_PROPERTY_AARCH64_FEATURE_1_BTI;
+      break;
+
+    default:
+      break;
+    }
+  elf_aarch64_tdata (output_bfd)->plt_type = bp_info.plt_type;
+  setup_plt_values (link_info, bp_info.plt_type);
 }
 
 static bfd_vma
@@ -8349,7 +8467,7 @@ elfNN_aarch64_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
 	  /* Make room for this entry. For now we only create the
 	     small model PLT entries. We later need to find a way
 	     of relaxing into these from the large model PLT entries.  */
-	  s->size += PLT_SMALL_ENTRY_SIZE;
+	  s->size += htab->plt_entry_size;
 
 	  /* We also need to make an entry in the .got.plt section, which
 	     will be placed in the .got section by the linker script.  */
@@ -8849,10 +8967,10 @@ elfNN_aarch64_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
   if (htab->tlsdesc_plt)
     {
       if (htab->root.splt->size == 0)
-	htab->root.splt->size += PLT_ENTRY_SIZE;
+	htab->root.splt->size += htab->plt_header_size;
 
       htab->tlsdesc_plt = htab->root.splt->size;
-      htab->root.splt->size += PLT_TLSDESC_ENTRY_SIZE;
+      htab->root.splt->size += htab->tlsdesc_plt_entry_size;
 
       /* If we're not using lazy TLS relocations, don't generate the
 	 GOT entry required.  */
@@ -8964,6 +9082,10 @@ elfNN_aarch64_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
 	      && (!add_dynamic_entry (DT_TLSDESC_PLT, 0)
 		  || !add_dynamic_entry (DT_TLSDESC_GOT, 0)))
 	    return FALSE;
+
+	  if ((elf_aarch64_tdata (output_bfd)->plt_type == PLT_BTI)
+	      && !add_dynamic_entry (DT_AARCH64_BTI_PLT, 0))
+	    return FALSE;
 	}
 
       if (relocs)
@@ -9060,7 +9182,13 @@ elfNN_aarch64_create_small_pltn_entry (struct elf_link_hash_entry *h,
     gotplt->output_offset + got_offset;
 
   /* Copy in the boiler-plate for the PLTn entry.  */
-  memcpy (plt_entry, elfNN_aarch64_small_plt_entry, PLT_SMALL_ENTRY_SIZE);
+  memcpy (plt_entry, htab->plt_entry, htab->plt_entry_size);
+
+  /* First instruction in BTI enabled PLT stub is a BTI
+     instruction so skip it.  */
+  if (elf_aarch64_tdata (output_bfd)->plt_type & PLT_BTI
+      && elf_elfheader (output_bfd)->e_type == ET_EXEC)
+    plt_entry = plt_entry + 4;
 
   /* Fill in the top 21 bits for this: ADRP x16, PLT_GOT + n * 8.
      ADRP:   ((PG(S+A)-PG(P)) >> 12) & 0x1fffff */
@@ -9365,10 +9493,10 @@ elfNN_aarch64_init_small_plt0_entry (bfd *output_bfd ATTRIBUTE_UNUSED,
   bfd_vma plt_base;
 
 
-  memcpy (htab->root.splt->contents, elfNN_aarch64_small_plt0_entry,
-	  PLT_ENTRY_SIZE);
+  memcpy (htab->root.splt->contents, htab->plt0_entry,
+	  htab->plt_header_size);
   elf_section_data (htab->root.splt->output_section)->this_hdr.sh_entsize =
-    PLT_ENTRY_SIZE;
+    htab->plt_header_size;
 
   plt_got_2nd_ent = (htab->root.sgotplt->output_section->vma
 		  + htab->root.sgotplt->output_offset
@@ -9377,18 +9505,24 @@ elfNN_aarch64_init_small_plt0_entry (bfd *output_bfd ATTRIBUTE_UNUSED,
   plt_base = htab->root.splt->output_section->vma +
     htab->root.splt->output_offset;
 
+  /* First instruction in BTI enabled PLT stub is a BTI
+     instruction so skip it.  */
+  bfd_byte *plt0_entry = htab->root.splt->contents;
+  if (elf_aarch64_tdata (output_bfd)->plt_type & PLT_BTI)
+    plt0_entry = plt0_entry + 4;
+
   /* Fill in the top 21 bits for this: ADRP x16, PLT_GOT + n * 8.
      ADRP:   ((PG(S+A)-PG(P)) >> 12) & 0x1fffff */
   elf_aarch64_update_plt_entry (output_bfd, BFD_RELOC_AARCH64_ADR_HI21_PCREL,
-				htab->root.splt->contents + 4,
+				plt0_entry + 4,
 				PG (plt_got_2nd_ent) - PG (plt_base + 4));
 
   elf_aarch64_update_plt_entry (output_bfd, BFD_RELOC_AARCH64_LDSTNN_LO12,
-				htab->root.splt->contents + 8,
+				plt0_entry + 8,
 				PG_OFFSET (plt_got_2nd_ent));
 
   elf_aarch64_update_plt_entry (output_bfd, BFD_RELOC_AARCH64_ADD_LO12,
-				htab->root.splt->contents + 12,
+				plt0_entry + 12,
 				PG_OFFSET (plt_got_2nd_ent));
 }
 
@@ -9472,9 +9606,18 @@ elfNN_aarch64_finish_dynamic_sections (bfd *output_bfd,
 	  bfd_put_NN (output_bfd, (bfd_vma) 0,
 		      htab->root.sgot->contents + htab->dt_tlsdesc_got);
 
+	  const bfd_byte *entry = elfNN_aarch64_tlsdesc_small_plt_entry;
+	  htab->tlsdesc_plt_entry_size = PLT_TLSDESC_ENTRY_SIZE;
+
+	  aarch64_plt_type type = elf_aarch64_tdata (output_bfd)->plt_type;
+	  if (type == PLT_BTI)
+	    {
+	      entry = elfNN_aarch64_tlsdesc_small_plt_bti_entry;
+	      htab->tlsdesc_plt_entry_size = PLT_BTI_TLSDESC_ENTRY_SIZE;
+	    }
+
 	  memcpy (htab->root.splt->contents + htab->tlsdesc_plt,
-		  elfNN_aarch64_tlsdesc_small_plt_entry,
-		  sizeof (elfNN_aarch64_tlsdesc_small_plt_entry));
+		  entry, htab->tlsdesc_plt_entry_size);
 
 	  {
 	    bfd_vma adrp1_addr =
@@ -9496,6 +9639,15 @@ elfNN_aarch64_finish_dynamic_sections (bfd *output_bfd,
 	    bfd_byte *plt_entry =
 	      htab->root.splt->contents + htab->tlsdesc_plt;
 
+	   /* First instruction in BTI enabled PLT stub is a BTI
+	      instruction so skip it.  */
+	    if (type & PLT_BTI)
+	      {
+		plt_entry = plt_entry + 4;
+		adrp1_addr = adrp1_addr + 4;
+		adrp2_addr = adrp2_addr + 4;
+	      }
+
 	    /* adrp x2, DT_TLSDESC_GOT */
 	    elf_aarch64_update_plt_entry (output_bfd,
 					  BFD_RELOC_AARCH64_ADR_HI21_PCREL,
@@ -9574,6 +9726,53 @@ elfNN_aarch64_finish_dynamic_sections (bfd *output_bfd,
   return TRUE;
 }
 
+/* Check if BTI enabled PLTs are needed.  Returns the type needed.  */
+static aarch64_plt_type
+get_plt_type (bfd *abfd)
+{
+  aarch64_plt_type ret = PLT_NORMAL;
+  bfd_byte *contents, *extdyn, *extdynend;
+  asection *sec = bfd_get_section_by_name (abfd, ".dynamic");
+  if (!sec || !bfd_malloc_and_get_section (abfd, sec, &contents))
+    return ret;
+  extdyn = contents;
+  extdynend = contents + sec->size;
+  for (; extdyn < extdynend; extdyn += sizeof (ElfNN_External_Dyn))
+    {
+      Elf_Internal_Dyn dyn;
+      bfd_elfNN_swap_dyn_in (abfd, extdyn, &dyn);
+
+      /* Let's check the processor specific dynamic array tags.  */
+      bfd_vma tag = dyn.d_tag;
+      if (tag < DT_LOPROC || tag > DT_HIPROC)
+	continue;
+
+      switch (tag)
+	{
+	case DT_AARCH64_BTI_PLT:
+	  ret = PLT_BTI;
+	  break;
+
+	default: break;
+	}
+    }
+  free (contents);
+  return ret;
+}
+
+static long
+elfNN_aarch64_get_synthetic_symtab (bfd *abfd,
+				    long symcount,
+				    asymbol **syms,
+				    long dynsymcount,
+				    asymbol **dynsyms,
+				    asymbol **ret)
+{
+  elf_aarch64_tdata (abfd)->plt_type = get_plt_type (abfd);
+  return _bfd_elf_get_synthetic_symtab (abfd, symcount, syms,
+					dynsymcount, dynsyms, ret);
+}
+
 /* Return address for Ith PLT stub in section PLT, for relocation REL
    or (bfd_vma) -1 if it should not be included.  */
 
@@ -9581,7 +9780,16 @@ static bfd_vma
 elfNN_aarch64_plt_sym_val (bfd_vma i, const asection *plt,
 			   const arelent *rel ATTRIBUTE_UNUSED)
 {
-  return plt->vma + PLT_ENTRY_SIZE + i * PLT_SMALL_ENTRY_SIZE;
+  size_t plt0_size = PLT_ENTRY_SIZE;
+  size_t pltn_size = PLT_SMALL_ENTRY_SIZE;
+
+  if (elf_aarch64_tdata (plt->owner)->plt_type == PLT_BTI)
+    {
+      plt0_size = PLT_BTI_ENTRY_SIZE;
+      if (elf_elfheader (plt->owner)->e_type == ET_EXEC)
+	pltn_size = PLT_BTI_SMALL_ENTRY_SIZE;
+    }
+  return plt->vma + plt0_size + i * pltn_size;
 }
 
 /* Returns TRUE if NAME is an AArch64 mapping symbol.
@@ -9627,6 +9835,9 @@ 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;
+  elf_aarch64_tdata (info->output_bfd)->plt_type
+    |= (prop & GNU_PROPERTY_AARCH64_FEATURE_1_BTI) ? PLT_BTI : 0;
+  setup_plt_values (info, elf_aarch64_tdata (info->output_bfd)->plt_type);
   return pbfd;
 }
 
@@ -9718,6 +9929,9 @@ const struct elf_size_info elfNN_aarch64_size_info =
 #define bfd_elfNN_find_nearest_line		\
   elfNN_aarch64_find_nearest_line
 
+#define bfd_elfNN_get_synthetic_symtab		\
+  elfNN_aarch64_get_synthetic_symtab
+
 #define bfd_elfNN_mkobject			\
   elfNN_aarch64_mkobject
 
diff --git a/binutils/readelf.c b/binutils/readelf.c
index 7446ffeee21961bf56b12ff16afbf52e5cd35387..f4775b439fc6a14a14699c88af3fe5f07648352e 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -1798,6 +1798,17 @@ dump_relocations (Filedata *          filedata,
 }
 
 static const char *
+get_aarch64_dynamic_type (unsigned long type)
+{
+  switch (type)
+    {
+    case DT_AARCH64_BTI_PLT:  return "AARCH64_BTI_PLT";
+    default:
+      return NULL;
+    }
+}
+
+static const char *
 get_mips_dynamic_type (unsigned long type)
 {
   switch (type)
@@ -2170,6 +2181,9 @@ get_dynamic_type (Filedata * filedata, unsigned long type)
 
 	  switch (filedata->file_header.e_machine)
 	    {
+	    case EM_AARCH64:
+	      result = get_aarch64_dynamic_type (type);
+	      break;
 	    case EM_MIPS:
 	    case EM_MIPS_RS3_LE:
 	      result = get_mips_dynamic_type (type);
@@ -9345,6 +9359,20 @@ process_unwind (Filedata * filedata)
 }
 
 static void
+dynamic_section_aarch64_val (Elf_Internal_Dyn * entry)
+{
+  switch (entry->d_tag)
+    {
+    case DT_AARCH64_BTI_PLT:
+      break;
+    default:
+      print_vma (entry->d_un.d_ptr, PREFIX_HEX);
+      break;
+    }
+  putchar ('\n');
+}
+
+static void
 dynamic_section_mips_val (Elf_Internal_Dyn * entry)
 {
   switch (entry->d_tag)
@@ -10358,6 +10386,9 @@ process_dynamic_section (Filedata * filedata)
 	    {
 	      switch (filedata->file_header.e_machine)
 		{
+		case EM_AARCH64:
+		  dynamic_section_aarch64_val (entry);
+		  break;
 		case EM_MIPS:
 		case EM_MIPS_RS3_LE:
 		  dynamic_section_mips_val (entry);
diff --git a/include/elf/aarch64.h b/include/elf/aarch64.h
index 3133ea6f6653eefc846da224e14fc6974cb2bf54..b86a1006297891d38f55f0c29d0ac51056b0c6e3 100644
--- a/include/elf/aarch64.h
+++ b/include/elf/aarch64.h
@@ -35,6 +35,8 @@
 						entry point.  */
 #define SHF_COMDEF		0x80000000   /* Section may be multiply defined
 						in the input to a link step.  */
+/* Processor specific dynamic array tags.  */
+#define DT_AARCH64_BTI_PLT	(DT_LOPROC + 1)
 
 /* Relocation types.  */
 
diff --git a/ld/NEWS b/ld/NEWS
index dcf11854f528028820cbe1983bbcdd5753d97eaf..31731219ad546483ae92a7e32862986627bfc4d4 100644
--- a/ld/NEWS
+++ b/ld/NEWS
@@ -10,6 +10,9 @@ Changes in 2.33:
 * Add support for GNU_PROPERTY_AARCH64_FEATURE_1_PAC in ELF GNU program
   properties in the AArch64 ELF linker.
 
+* Add --bti-nowarn for AArch64 to enable GNU_PROPERTY_AARCH64_FEATURE_1_BTI
+  on output without any warnings and use PLTs protected with BTI.
+
 Changes in 2.32:
 
 * Report property change in linker map file when merging GNU properties.
diff --git a/ld/emultempl/aarch64elf.em b/ld/emultempl/aarch64elf.em
index 45e40b510cf0da21e777f5734dcc9d1be54918a5..146bfad31fd299ef5c170b269e86afd0f3e1f5b9 100644
--- a/ld/emultempl/aarch64elf.em
+++ b/ld/emultempl/aarch64elf.em
@@ -33,6 +33,8 @@ static int pic_veneer = 0;
 static int fix_erratum_835769 = 0;
 static int fix_erratum_843419 = 0;
 static int no_apply_dynamic_relocs = 0;
+static aarch64_plt_type plt_type = PLT_NORMAL;
+static aarch64_enable_bti_type bti_type = BTI_NONE;
 
 static void
 gld${EMULATION_NAME}_before_parse (void)
@@ -308,12 +310,17 @@ aarch64_elf_create_output_section_statements (void)
       return;
     }
 
+  aarch64_bti_pac_info bp_info;
+  bp_info.plt_type = plt_type;
+  bp_info.bti_type = bti_type;
+
   bfd_elf${ELFSIZE}_aarch64_set_options (link_info.output_bfd, &link_info,
 				 no_enum_size_warning,
 				 no_wchar_size_warning,
 				 pic_veneer,
 				 fix_erratum_835769, fix_erratum_843419,
-				 no_apply_dynamic_relocs);
+				 no_apply_dynamic_relocs,
+				 bp_info);
 
   stub_file = lang_add_input_file ("linker stubs",
 				   lang_input_file_is_fake_enum,
@@ -365,6 +372,7 @@ PARSE_AND_LIST_PROLOGUE='
 #define OPTION_FIX_ERRATUM_835769	313
 #define OPTION_FIX_ERRATUM_843419	314
 #define OPTION_NO_APPLY_DYNAMIC_RELOCS	315
+#define OPTION_BTI_NOWARN		316
 '
 
 PARSE_AND_LIST_SHORTOPTS=p
@@ -378,6 +386,7 @@ PARSE_AND_LIST_LONGOPTS='
   { "fix-cortex-a53-835769", no_argument, NULL, OPTION_FIX_ERRATUM_835769},
   { "fix-cortex-a53-843419", no_argument, NULL, OPTION_FIX_ERRATUM_843419},
   { "no-apply-dynamic-relocs", no_argument, NULL, OPTION_NO_APPLY_DYNAMIC_RELOCS},
+  { "bti-nowarn", no_argument, NULL, OPTION_BTI_NOWARN},
 '
 
 PARSE_AND_LIST_OPTIONS='
@@ -398,6 +407,7 @@ PARSE_AND_LIST_OPTIONS='
   fprintf (file, _("  --fix-cortex-a53-835769      Fix erratum 835769\n"));
   fprintf (file, _("  --fix-cortex-a53-843419      Fix erratum 843419\n"));
   fprintf (file, _("  --no-apply-dynamic-relocs    Do not apply link-time values for dynamic relocations\n"));
+  fprintf (file, _("  --bti-nowarn                 Turn on Branch Target Identification mechanism and generate PLTs with BTI. Generate no warnings for missing BTI on inputs\n"));
 '
 
 PARSE_AND_LIST_ARGS_CASES='
@@ -429,6 +439,11 @@ PARSE_AND_LIST_ARGS_CASES='
       no_apply_dynamic_relocs = 1;
       break;
 
+    case OPTION_BTI_NOWARN:
+      plt_type |= PLT_BTI;
+      bti_type = BTI_NOWARN;
+      break;
+
     case OPTION_STUBGROUP_SIZE:
       {
 	const char *end;
diff --git a/ld/testsuite/ld-aarch64/aarch64-elf.exp b/ld/testsuite/ld-aarch64/aarch64-elf.exp
index c6fefbbd5c3f7e5516086c7eca0e056ae243d36d..ed0bca5b081c5c016b3f8e96619b76820aa1525d 100644
--- a/ld/testsuite/ld-aarch64/aarch64-elf.exp
+++ b/ld/testsuite/ld-aarch64/aarch64-elf.exp
@@ -374,6 +374,8 @@ 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"
+run_dump_test "bti-plt-1"
+run_dump_test "bti-plt-2"
 
 set aarch64elflinktests {
   {"ld-aarch64/so with global symbol" "-shared" "" "" {copy-reloc-so.s}
@@ -389,6 +391,12 @@ set aarch64elflinktests {
   {"ld-aarch64/func sym hash opt for exe"
    "-e0 --hash-style=gnu tmpdir/func-in-so.so" "" ""
     {func-sym-hash-opt.s} {{readelf --dyn-sym func-sym-hash-opt.d}} "hash-opt"}
+  {"Build bti-plt-so for PLT tests" "-shared" "" "" {bti-plt-so.s}
+    {} "libbti-plt-so.so"}
 }
 
 run_ld_link_tests $aarch64elflinktests
+
+run_dump_test "bti-plt-3"
+run_dump_test "bti-plt-4"
+run_dump_test "bti-plt-5"
diff --git a/ld/testsuite/ld-aarch64/bti-plt-1.d b/ld/testsuite/ld-aarch64/bti-plt-1.d
new file mode 100644
index 0000000000000000000000000000000000000000..16c71024989c4ecd6bc2fc2356956ac7a4c0debf
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/bti-plt-1.d
@@ -0,0 +1,32 @@
+#name: Check --bti-nowarn emits BTI PLT (shared)
+#source: bti-plt-1.s
+#as: -mabi=lp64
+#ld: -shared --bti-nowarn -T bti-plt.ld
+#objdump: -dr -j .plt
+
+[^:]*: *file format elf64-.*aarch64
+
+Disassembly of section \.plt:
+
+[0-9]+ <.*>:
+.*:	d503245f 	bti	c
+.*:	a9bf7bf0 	stp	x16, x30, \[sp, #-16\]!
+.*:	90000090 	adrp	x16, 28000 <_GLOBAL_OFFSET_TABLE_>
+.*:	f9400e11 	ldr	x17, \[x16, #24\]
+.*:	91006210 	add	x16, x16, #0x18
+.*:	d61f0220 	br	x17
+.*:	d503201f 	nop
+.*:	d503201f 	nop
+.*:	d503201f 	nop
+
+[0-9]+ <.*>:
+.*:	90000090 	adrp	x16, 28000 <_GLOBAL_OFFSET_TABLE_>
+.*:	f9401211 	ldr	x17, \[x16, #32\]
+.*:	91008210 	add	x16, x16, #0x20
+.*:	d61f0220 	br	x17
+
+[0-9]+ <.*>:
+.*:	90000090 	adrp	x16, 28000 <_GLOBAL_OFFSET_TABLE_>
+.*:	f9401611 	ldr	x17, \[x16, #40\]
+.*:	9100a210 	add	x16, x16, #0x28
+.*:	d61f0220 	br	x17
diff --git a/ld/testsuite/ld-aarch64/bti-plt-1.s b/ld/testsuite/ld-aarch64/bti-plt-1.s
new file mode 100644
index 0000000000000000000000000000000000000000..9cd7cc467b32d13b8531a0c183b6e50d78971ef6
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/bti-plt-1.s
@@ -0,0 +1,6 @@
+	.text
+	.globl _start
+	.type _start,@function
+_start:
+	bl foo
+	bl bar
diff --git a/ld/testsuite/ld-aarch64/bti-plt-2.d b/ld/testsuite/ld-aarch64/bti-plt-2.d
new file mode 100644
index 0000000000000000000000000000000000000000..2c7cc0df8d4a165193bb7299b93ce814ed81f4dc
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/bti-plt-2.d
@@ -0,0 +1,11 @@
+#name: Check --bti-nowarn emits BTI feature (shared)
+#source: bti-plt-1.s
+#source: bti-plt-2.s
+#as: -mabi=lp64
+#ld: -shared --bti-nowarn -T bti-plt.ld
+#readelf: -n
+
+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/bti-plt-2.s b/ld/testsuite/ld-aarch64/bti-plt-2.s
new file mode 100644
index 0000000000000000000000000000000000000000..4c29bb879c80eea377ae666de4f5f3fac01b472f
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/bti-plt-2.s
@@ -0,0 +1,6 @@
+	.text
+	.globl _start
+	.type _start,@function
+func2:
+	bl foo2
+	bl bar2
diff --git a/ld/testsuite/ld-aarch64/bti-plt-3.d b/ld/testsuite/ld-aarch64/bti-plt-3.d
new file mode 100644
index 0000000000000000000000000000000000000000..47116cc21db775ae1470198d6ef7c6f99f09eb43
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/bti-plt-3.d
@@ -0,0 +1,34 @@
+#name: Check --bti-nowarn emits BTI PLT (exec)
+#source: bti-plt-1.s
+#as: -mabi=lp64
+#ld: --bti-nowarn -e _start -T bti-plt.ld -L./tmpdir -lbti-plt-so
+#objdump: -dr -j .plt
+
+[^:]*: *file format elf64-.*aarch64
+
+Disassembly of section \.plt:
+
+[0-9]+ <.*>:
+.*:	d503245f 	bti	c
+.*:	a9bf7bf0 	stp	x16, x30, \[sp, #-16\]!
+.*:	90000090 	adrp	x16, 28000 <_GLOBAL_OFFSET_TABLE_>
+.*:	f9400e11 	ldr	x17, \[x16, #24\]
+.*:	91006210 	add	x16, x16, #0x18
+.*:	d61f0220 	br	x17
+.*:	d503201f 	nop
+.*:	d503201f 	nop
+.*:	d503201f 	nop
+
+[0-9]+ <.*>:
+.*:	d503245f 	bti	c
+.*:	90000090 	adrp	x16, 28000 <_GLOBAL_OFFSET_TABLE_>
+.*:	f9401211 	ldr	x17, \[x16, #32\]
+.*:	91008210 	add	x16, x16, #0x20
+.*:	d61f0220 	br	x17
+
+[0-9]+ <.*>:
+.*:	d503245f 	bti	c
+.*:	90000090 	adrp	x16, 28000 <_GLOBAL_OFFSET_TABLE_>
+.*:	f9401611 	ldr	x17, \[x16, #40\]
+.*:	9100a210 	add	x16, x16, #0x28
+.*:	d61f0220 	br	x17
diff --git a/ld/testsuite/ld-aarch64/bti-plt-4.d b/ld/testsuite/ld-aarch64/bti-plt-4.d
new file mode 100644
index 0000000000000000000000000000000000000000..92949c0c7325121710892193f19b04c8f1e9fe29
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/bti-plt-4.d
@@ -0,0 +1,10 @@
+#name: Check --bti-nowarn emits BTI feature (exec)
+#source: bti-plt-1.s
+#as: -mabi=lp64
+#ld: --bti-nowarn -e _start -T bti-plt.ld -L./tmpdir -lbti-plt-so
+#readelf: -n
+
+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/bti-plt-5.d b/ld/testsuite/ld-aarch64/bti-plt-5.d
new file mode 100644
index 0000000000000000000000000000000000000000..01231b69d2c4066d0fe3c49e359cef9b670ba34d
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/bti-plt-5.d
@@ -0,0 +1,28 @@
+#name: BTI PLT with only GNU PROP
+#source: property-bti-pac1.s
+#as: -mabi=lp64 -defsym __property_bti__=1
+#ld: -e _start -L./tmpdir -lbti-plt-so
+#objdump: -dr -j .plt
+#target: *linux*
+
+[^:]*: *file format elf64-.*aarch64
+
+Disassembly of section \.plt:
+
+[0-9a-f]+ <.*>:
+.*:	d503245f 	bti	c
+.*:	a9bf7bf0 	stp	x16, x30, \[sp, #-16\]!
+.*:	90000090 	adrp	x16, 410000 <_start\+0xfd28>
+.*:	f9421611 	ldr	x17, \[x16, #1064\]
+.*:	9110a210 	add	x16, x16, #0x428
+.*:	d61f0220 	br	x17
+.*:	d503201f 	nop
+.*:	d503201f 	nop
+.*:	d503201f 	nop
+
+[0-9a-f]+ <.*>:
+.*:	d503245f 	bti	c
+.*:	90000090 	adrp	x16, 410000 <_start\+0xfd28>
+.*:	f9421a11 	ldr	x17, \[x16, #1072\]
+.*:	9110c210 	add	x16, x16, #0x430
+.*:	d61f0220 	br	x17
diff --git a/ld/testsuite/ld-aarch64/bti-plt-so.s b/ld/testsuite/ld-aarch64/bti-plt-so.s
new file mode 100644
index 0000000000000000000000000000000000000000..d335af02536eefa77bea9ebbf5f1407817b42fa0
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/bti-plt-so.s
@@ -0,0 +1,26 @@
+	.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
+bar:
+	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	bar, .-bar
diff --git a/ld/testsuite/ld-aarch64/bti-plt.ld b/ld/testsuite/ld-aarch64/bti-plt.ld
new file mode 100644
index 0000000000000000000000000000000000000000..8682623d69b97cd735a7459838c0ce547723c337
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/bti-plt.ld
@@ -0,0 +1,14 @@
+OUTPUT_ARCH(aarch64)
+ENTRY(_start)
+SECTIONS
+{
+  . = 0x10000;
+  .rela.plt       : { *(.rela.plt) *(.rela.iplt) }
+  . = 0x18000;
+  .plt            : { *(.plt) *(.iplt) }
+  . = 0x20000;
+  .text           : { *(.text) }
+  . = 0x28000;
+  .got            : { *(.got) *(.got.plt) }
+  .ARM.attributes 0 : { *(.ARM.atttributes) }
+}

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

* [PATCH, BFD, LD, AArch64, 3/4] Add --bti to enable BTI and select BTI enabled PLTs but also warn for missing NOTE sections.
  2019-03-06 10:34   ` [PATCH, BFD, LD, AArch64, 2/4] Add --bti-nowarn to enable BTI without warning and to select BTI enabled PLTs Sudakshina Das
@ 2019-03-06 10:36     ` Sudakshina Das
  2019-03-06 10:39       ` [PATCH, BFD, LD, AArch64, 4/4] Add --pac-plt to enable PLTs protected with PAC Sudakshina Das
  0 siblings, 1 reply; 22+ messages in thread
From: Sudakshina Das @ 2019-03-06 10:36 UTC (permalink / raw)
  To: binutils; +Cc: nd, nickc, Ramana Radhakrishnan

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

Hi

On 06/03/2019 10:34, Sudakshina Das wrote:
> Hi
> 
> On 06/03/2019 10:30, Sudakshina Das wrote:
>> Hi
>>
>> On 06/03/2019 10:26, Sudakshina Das wrote:
>>> Hi
>>>
>>> This patch series is aimed at giving support for the new Armv8.3-A 
>>> Pointer Authentication and Armv8.5-A Branch Target Identification 
>>> feature in the linker.
>>>
>>> In order to support these, we propose to make the following changes:
>>> 1) We have defined .note.gnu.property for AArch64.
>>> 2) We have defined a new Program Property type
>>> GNU_PROPERTY_AARCH64_FEATURE_1_AND and used 2 bits to represent
>>> BTI and PAC respectively.
>>>    - GNU_PROPERTY_AARCH64_FEATURE_1_BTI
>>>    - GNU_PROPERTY_AARCH64_FEATURE_1_PAC (We have only reserved this bit
>>>      for now.)
>>> 3) We also need custom PLTs when these features are turned on and thus
>>> we have defined the following processor-specific dynamic array tags:
>>>    - DT_AARCH64_BTI_PLT
>>>    - DT_AARCH64_PAC_PLT
>>> Details of these can be found in the new AArch64 ELF documentation:
>>> https://developer.arm.com/docs/ihi0056/latest/elf-for-the-arm-64-bit-architecture-aarch64-abi-2018q4 
>>>
>>>
>>> Command line options:
>>> We introduce a new set of command line options for the linker in 
>>> order to support the correct PLTs
>>> 1) --pac-plt : In the presence of this option, the linker uses a PAC 
>>> enabled PLT. It also uses the dynamic tag DT_AARCH64_PAC_PLT to 
>>> reflect the same. Other tools like Objdump can use this to determine 
>>> the size of the PLTs.
>>> 2) --bti: In the presence of this option, the linker enables BTI with 
>>> the GNU_PROPERTY_AARCH64_FEATURE_1_BTI feature and also uses a BTI 
>>> enabled PLT. It also uses the dynamic tag DT_AARCH64_BTI_PLT to 
>>> reflect the choice of the PLTs. Other tools like Objdump can use this 
>>> to determine the size of the PLTs. Using this option can give a 
>>> warning if not all input objects are marked with 
>>> GNU_PROPERTY_AARCH64_FEATURE_1_BTI.
>>> 3)--bti-nowarn - Same as above but does not emit any warnings.
>>>
>>> In terms of the PLTs, in the presence of both --pac-plt and 
>>> --bti/--bti-nowarn, the linker chooses the PLTs protected with both 
>>> BTI and PAC and uses both DT_AARCH64_PAC_PLT and DT_AARCH64_BTI_PLT.
>>>
>>> Interaction between Command line arguments and GNU NOTE section
>>> 1) For PAC, in the presence of --pac-plt along with BIND_NOW, the 
>>> linker can choose to ignore the pac-plt directive and use smaller 
>>> PLTs without compromising on security,
>>> 2) For BTI, the linker must also check for the 
>>> GNU_PROPERTY_AARCH64_FEATURE_1_BTI in its input. If all inputs have 
>>> GNU_PROPERTY_AARCH64_FEATURE_1_BTI, the final output will also be 
>>> marked as such. The PLT should also be protected with a BTI PLT in 
>>> this case. Thus even if there is no linker option to use BTI PLT, the 
>>> linker
>>> should be able to use them depending on the NOTE section. The user 
>>> can use the linker option --bti, to make sure that their intention of 
>>> having all input objects (and hence the output) marked with BTI is 
>>> not disrupted by any stray objects as this option will warn about it.
>>>
>>>
>>> The following patches implement these changes as follows:
>>> [1/4] Add support for GNU PROPERTIES in AArch64 for BTI and PAC:
>>> [2/4] Add --bti-nowarn to enable BTI without warning and to select 
>>> BTI enabled PLTs
>>> [3/4] Add --bti to enable BTI and select BTI enabled PLTs but also 
>>> warn for missing NOTE sections.
>>> [4/4] Add --pac-plt to enable PLTs protected with PAC.
>>>
>>> This is my first time making such intrusive changes to the linker. 
>>> Please be kind :P
>>>
>>> Thanks
>>> Sudi
>>
>> 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 
>>
>>
>> Build and regression tests all pass on aarch64-none-linux-gnu and
>> new tests are added.
>>
>> Is this ok for trunk?
>>
>> Thanks
>> Sudi
>>
>> *** bfd/ChangeLog ***
>>
>> 2019-xx-xx  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-xx-xx  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-xx-xx  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-xx-xx  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.
> 
> This is part of the patch series to add support for BTI and
> PAC in AArch64 linker.
> 
> 1) This patch adds a new ld command line option: --bti-nowarn.
> In the presence of this option, the linker enables BTI with the
> GNU_PROPERTY_AARCH64_FEATURE_1_BTI feature. This gives no warning
> in case of missing gnu notes for BTI in inputs.
> 2) It also defines a new set of BTI enabled PLTs. These are used either
> when all the inputs are marked with GNU_PROPERTY_AARCH64_FEATURE_1_BTI
> or when the new --bti-nowarn option is used. This required adding new
> fields in elf_aarch64_link_hash_table so that we could make the PLT
> related information more generic.
> 3) It also defines a dynamic tag DT_AARCH64_BTI_PLT. The linker uses
> this whenever it picks BTI enabled PLTs.
> 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 
> 
> 
> Build and regression tests all pass on aarch64-none-linux-gnu and
> new tests are added.
> 
> Is this ok for trunk?
> 
> Thanks
> Sudi
> 
> *** bfd/ChangeLog ***
> 
> 2019-xx-xx  Sudakshina Das  <sudi.das@arm.com>
>          Szabolcs Nagy  <szabolcs.nagy@arm.com>
> 
>      * bfd-in.h (aarch64_plt_type, aarch64_enable_bti_type): New.
>      (aarch64_bti_pac_info): New.
>      (bfd_elf64_aarch64_set_options): Add aarch64_bti_pac_info argument.
>      (bfd_elf32_aarch64_set_options): Likewise.
>      * bfd-in2.h: Regenerate
>      * elfnn-aarch64.c (PLT_BTI_ENTRY_SIZE): New.
>      (PLT_BTI_SMALL_ENTRY_SIZE, PLT_BTI_TLSDESC_ENTRY_SIZE): New.
>      (elfNN_aarch64_small_plt0_bti_entry): New.
>      (elfNN_aarch64_small_plt_bti_entry): New.
>      (elfNN_aarch64_tlsdesc_small_plt_bti_entry): New.
>      (elf_aarch64_obj_tdata): Add no_enable_bti_warn and plt_type fields.
>      (elf_aarch64_link_hash_table): Add plt0_entry, plt_entry and
>      tlsdesc_plt_entry_size fields.
>      (elfNN_aarch64_link_hash_table_create): Initialise the new fields.
>      (setup_plt_values): New helper function.
>      (bfd_elfNN_aarch64_set_options): Use new bp_info to set plt sizes and
>      bti enable type.
>      (elfNN_aarch64_allocate_dynrelocs): Use new size members instead of
>      fixed macros.
>      (elfNN_aarch64_size_dynamic_sections): Likewise and add checks.
>      (elfNN_aarch64_create_small_pltn_entry): Use new generic pointers
>      to plt stubs instead of fixed ones and update filling them according
>      to the need for bti.
>      (elfNN_aarch64_init_small_plt0_entry): Likewise.
>      (elfNN_aarch64_finish_dynamic_sections): Likewise.
>      (get_plt_type, elfNN_aarch64_get_synthetic_symtab): New.
>      (elfNN_aarch64_plt_sym_val): Update size accordingly.
>      (elfNN_aarch64_link_setup_gnu_properties): Set up plts if BTI GNU NOTE
>      is set.
>      (bfd_elfNN_get_synthetic_symtab): Define.
> 
> *** binutils/ChangeLog ***
> 
> 2019-xx-xx  Sudakshina Das  <sudi.das@arm.com>
>          Szabolcs Nagy  <szabolcs.nagy@arm.com>
> 
>      * readelf.c (get_aarch64_dynamic_type): New.
>      (get_dynamic_type): Use above for EM_AARCH64.
>      (dynamic_section_aarch64_val): New.
>      (process_dynamic_section): Use above for EM_AARCH64.
> 
> *** include/ChangeLog ***
> 
> 2019-xx-xx  Sudakshina Das  <sudi.das@arm.com>
>          Szabolcs Nagy  <szabolcs.nagy@arm.com>
> 
>      * elf/aarch64.h (DT_AARCH64_BTI_PLT): New.
> 
> *** ld/ChangeLog ***
> 
> 2019-xx-xx  Sudakshina Das  <sudi.das@arm.com>
>          Szabolcs Nagy  <szabolcs.nagy@arm.com>
> 
>      * NEWS: Document --bti-nowarn.
>      * emultempl/aarch64elf.em (plt_type, bti_type, OPTION_BTI_NOWARN): 
> New.
>      (PARSE_AND_LIST_SHORTOPTS, PARSE_AND_LIST_OPTIONS): Add bti-nowarn.
>      (PARSE_AND_LIST_ARGS_CASES): Handle OPTION_BTI_NOWARN.
>      * testsuite/ld-aarch64/aarch64-elf.exp: Add all the tests below.
>      * testsuite/ld-aarch64/bti-plt-1.d: New test.
>      * testsuite/ld-aarch64/bti-plt-1.s: New test.
>      * testsuite/ld-aarch64/bti-plt-2.d: New test.
>      * testsuite/ld-aarch64/bti-plt-3.d: New test.
>      * testsuite/ld-aarch64/bti-plt-4.d: New test.
>      * testsuite/ld-aarch64/bti-plt-5.d: New test.
>      * testsuite/ld-aarch64/bti-plt-so.s: New test.
>      * testsuite/ld-aarch64/bti-plt.ld: New test.

This is part of the patch series to add support for BTI and
PAC in AArch64 linker.

This patch adds a new ld command line option: --bti.
In the presence of this option, the linker enables BTI with the
GNU_PROPERTY_AARCH64_FEATURE_1_BTI feature. It also uses the BTI
enabled PLTs and marks with DT_AARCH64_BTI_PLT. This also gives a
warning in case of missing gnu notes for BTI in inputs.
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

Build and regression tests all pass on aarch64-none-linux-gnu and
new tests are added.

Is this ok for trunk?

Thanks
Sudi

*** bfd/ChangeLog ***

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

	* elfnn-aarch64.c (elfNN_aarch64_merge_gnu_properties): Give out
	warning with --bti and mising BTI NOTE SECTION.

*** ld/ChangeLog ***

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

	* NEWS: Document --bti.
	* emultempl/aarch64elf.em (OPTION_BTI_WARN): Define.
	(PARSE_AND_LIST_LONGOPTS, PARSE_AND_LIST_OPTIONS): Add --bti.
	(PARSE_AND_LIST_ARGS_CASES): Handle OPTION_BTI_WARN.
	* testsuite/ld-aarch64/aarch64-elf.exp: Add below tests.
	* testsuite/ld-aarch64/bti-plt-6.d: New test.
	* testsuite/ld-aarch64/bti-plt-7.d: New test.

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: rb10236.patch --]
[-- Type: text/x-patch; name="rb10236.patch", Size: 5654 bytes --]

diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c
index 66fe86bbac45f2de1bce43c68036ff18ffb989a8..832de531131c82912275f2f40b475e3571cd53d5 100644
--- a/bfd/elfnn-aarch64.c
+++ b/bfd/elfnn-aarch64.c
@@ -9852,6 +9852,25 @@ elfNN_aarch64_merge_gnu_properties (struct bfd_link_info *info,
 {
   uint32_t prop
     = elf_aarch64_tdata (info->output_bfd)->gnu_and_prop;
+
+  /* If output has been marked with BTI using command line argument, give out
+     warning if necessary.  */
+  if ((prop & GNU_PROPERTY_AARCH64_FEATURE_1_BTI)
+      && (!elf_aarch64_tdata (info->output_bfd)->no_enable_bti_warn))
+    {
+      if ((aprop && !(aprop->u.number & GNU_PROPERTY_AARCH64_FEATURE_1_BTI))
+	  || (bprop && !(bprop->u.number & GNU_PROPERTY_AARCH64_FEATURE_1_BTI))
+	  /* If either property is NULL, it means its bfd did not have any
+	     property.  */
+	  || !aprop || !bprop)
+	{
+	  _bfd_error_handler (_("warning: BTI turned on by --bti when "
+				"all inputs do not have BTI in NOTE "
+				"section. If this was intentional use "
+				"--bti-nowarn to turn off the warning."));
+	}
+    }
+
   return  _bfd_aarch64_elf_merge_gnu_properties (info, abfd, aprop,
 						 bprop, prop);
 }
diff --git a/ld/NEWS b/ld/NEWS
index 31731219ad546483ae92a7e32862986627bfc4d4..e19870f741ad072d89e4f72a1c96d2903ad9d3fd 100644
--- a/ld/NEWS
+++ b/ld/NEWS
@@ -13,6 +13,10 @@ Changes in 2.33:
 * Add --bti-nowarn for AArch64 to enable GNU_PROPERTY_AARCH64_FEATURE_1_BTI
   on output without any warnings and use PLTs protected with BTI.
 
+* Add --bti for AArch64 to enable GNU_PROPERTY_AARCH64_FEATURE_1_BTI
+  on output while warning about missing GNU_PROPERTY_AARCH64_FEATURE_1_BTI
+  on inputs and use PLTs protected with BTI.
+
 Changes in 2.32:
 
 * Report property change in linker map file when merging GNU properties.
diff --git a/ld/emultempl/aarch64elf.em b/ld/emultempl/aarch64elf.em
index 146bfad31fd299ef5c170b269e86afd0f3e1f5b9..c2db3e9e531930f0659197219369da1ddb04275c 100644
--- a/ld/emultempl/aarch64elf.em
+++ b/ld/emultempl/aarch64elf.em
@@ -373,6 +373,7 @@ PARSE_AND_LIST_PROLOGUE='
 #define OPTION_FIX_ERRATUM_843419	314
 #define OPTION_NO_APPLY_DYNAMIC_RELOCS	315
 #define OPTION_BTI_NOWARN		316
+#define OPTION_BTI_WARN			317
 '
 
 PARSE_AND_LIST_SHORTOPTS=p
@@ -387,6 +388,7 @@ PARSE_AND_LIST_LONGOPTS='
   { "fix-cortex-a53-843419", no_argument, NULL, OPTION_FIX_ERRATUM_843419},
   { "no-apply-dynamic-relocs", no_argument, NULL, OPTION_NO_APPLY_DYNAMIC_RELOCS},
   { "bti-nowarn", no_argument, NULL, OPTION_BTI_NOWARN},
+  { "bti", no_argument, NULL, OPTION_BTI_WARN},
 '
 
 PARSE_AND_LIST_OPTIONS='
@@ -408,6 +410,7 @@ PARSE_AND_LIST_OPTIONS='
   fprintf (file, _("  --fix-cortex-a53-843419      Fix erratum 843419\n"));
   fprintf (file, _("  --no-apply-dynamic-relocs    Do not apply link-time values for dynamic relocations\n"));
   fprintf (file, _("  --bti-nowarn                 Turn on Branch Target Identification mechanism and generate PLTs with BTI. Generate no warnings for missing BTI on inputs\n"));
+  fprintf (file, _("  --bti                        Turn on Branch Target Identification mechanism and generate PLTs with BTI. Generate warnings for missing BTI on inputs\n"));
 '
 
 PARSE_AND_LIST_ARGS_CASES='
@@ -444,6 +447,11 @@ PARSE_AND_LIST_ARGS_CASES='
       bti_type = BTI_NOWARN;
       break;
 
+    case OPTION_BTI_WARN:
+      plt_type |= PLT_BTI;
+      bti_type = BTI_WARN;
+      break;
+
     case OPTION_STUBGROUP_SIZE:
       {
 	const char *end;
diff --git a/ld/testsuite/ld-aarch64/aarch64-elf.exp b/ld/testsuite/ld-aarch64/aarch64-elf.exp
index ed0bca5b081c5c016b3f8e96619b76820aa1525d..906534b230c8905fb97a6739e1c1411683455fe3 100644
--- a/ld/testsuite/ld-aarch64/aarch64-elf.exp
+++ b/ld/testsuite/ld-aarch64/aarch64-elf.exp
@@ -400,3 +400,5 @@ run_ld_link_tests $aarch64elflinktests
 run_dump_test "bti-plt-3"
 run_dump_test "bti-plt-4"
 run_dump_test "bti-plt-5"
+run_dump_test "bti-plt-6"
+run_dump_test "bti-plt-7"
diff --git a/ld/testsuite/ld-aarch64/bti-plt-6.d b/ld/testsuite/ld-aarch64/bti-plt-6.d
new file mode 100644
index 0000000000000000000000000000000000000000..0f94e89ba227abbcf2d01b0b0fd0c5be12db2f5c
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/bti-plt-6.d
@@ -0,0 +1,15 @@
+#name: Warn with one missing GNU NOTE BTI input
+#source: property-bti-pac1.s
+#source: property-bti-pac2.s
+#as: -mabi=lp64 -defsym __property_pac__=1
+#ld: -shared --bti
+#warning: .*: warning: BTI turned on by --bti.*$
+#readelf: -n
+
+# Should warn about the missing input BTI NOTE but should
+# still mark output as BTI
+
+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/bti-plt-7.d b/ld/testsuite/ld-aarch64/bti-plt-7.d
new file mode 100644
index 0000000000000000000000000000000000000000..e4fbac4d87d746d514d109b80ccc0d0105ef444d
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/bti-plt-7.d
@@ -0,0 +1,15 @@
+#name: Warn when neither inputs has GNU NOTE BTI
+#source: bti-plt-1.s
+#source: bti-plt-2.s
+#as: -mabi=lp64
+#ld: -shared --bti
+#warning: .*: warning: BTI turned on by --bti.*$
+#readelf: -n
+
+# Should warn about the missing input BTI NOTE but should
+# still mark output as BTI
+
+Displaying notes found in: .note.gnu.property
+  Owner                 Data size	Description
+  GNU                  0x00000010	NT_GNU_PROPERTY_TYPE_0
+      Properties: AArch64 feature: BTI

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

* [PATCH, BFD, LD, AArch64, 4/4] Add --pac-plt to enable PLTs protected with PAC.
  2019-03-06 10:36     ` [PATCH, BFD, LD, AArch64, 3/4] Add --bti to enable BTI and select BTI enabled PLTs but also warn for missing NOTE sections Sudakshina Das
@ 2019-03-06 10:39       ` Sudakshina Das
  2019-04-11 14:47         ` Szabolcs Nagy
  0 siblings, 1 reply; 22+ messages in thread
From: Sudakshina Das @ 2019-03-06 10:39 UTC (permalink / raw)
  To: binutils; +Cc: nd, nickc, Ramana Radhakrishnan

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

Hi

On 06/03/2019 10:36, Sudakshina Das wrote:
> Hi
> 
> On 06/03/2019 10:34, Sudakshina Das wrote:
>> Hi
>>
>> On 06/03/2019 10:30, Sudakshina Das wrote:
>>> Hi
>>>
>>> On 06/03/2019 10:26, Sudakshina Das wrote:
>>>> Hi
>>>>
>>>> This patch series is aimed at giving support for the new Armv8.3-A 
>>>> Pointer Authentication and Armv8.5-A Branch Target Identification 
>>>> feature in the linker.
>>>>
>>>> In order to support these, we propose to make the following changes:
>>>> 1) We have defined .note.gnu.property for AArch64.
>>>> 2) We have defined a new Program Property type
>>>> GNU_PROPERTY_AARCH64_FEATURE_1_AND and used 2 bits to represent
>>>> BTI and PAC respectively.
>>>>    - GNU_PROPERTY_AARCH64_FEATURE_1_BTI
>>>>    - GNU_PROPERTY_AARCH64_FEATURE_1_PAC (We have only reserved this bit
>>>>      for now.)
>>>> 3) We also need custom PLTs when these features are turned on and thus
>>>> we have defined the following processor-specific dynamic array tags:
>>>>    - DT_AARCH64_BTI_PLT
>>>>    - DT_AARCH64_PAC_PLT
>>>> Details of these can be found in the new AArch64 ELF documentation:
>>>> https://developer.arm.com/docs/ihi0056/latest/elf-for-the-arm-64-bit-architecture-aarch64-abi-2018q4 
>>>>
>>>>
>>>> Command line options:
>>>> We introduce a new set of command line options for the linker in 
>>>> order to support the correct PLTs
>>>> 1) --pac-plt : In the presence of this option, the linker uses a PAC 
>>>> enabled PLT. It also uses the dynamic tag DT_AARCH64_PAC_PLT to 
>>>> reflect the same. Other tools like Objdump can use this to determine 
>>>> the size of the PLTs.
>>>> 2) --bti: In the presence of this option, the linker enables BTI 
>>>> with the GNU_PROPERTY_AARCH64_FEATURE_1_BTI feature and also uses a 
>>>> BTI enabled PLT. It also uses the dynamic tag DT_AARCH64_BTI_PLT to 
>>>> reflect the choice of the PLTs. Other tools like Objdump can use 
>>>> this to determine the size of the PLTs. Using this option can give a 
>>>> warning if not all input objects are marked with 
>>>> GNU_PROPERTY_AARCH64_FEATURE_1_BTI.
>>>> 3)--bti-nowarn - Same as above but does not emit any warnings.
>>>>
>>>> In terms of the PLTs, in the presence of both --pac-plt and 
>>>> --bti/--bti-nowarn, the linker chooses the PLTs protected with both 
>>>> BTI and PAC and uses both DT_AARCH64_PAC_PLT and DT_AARCH64_BTI_PLT.
>>>>
>>>> Interaction between Command line arguments and GNU NOTE section
>>>> 1) For PAC, in the presence of --pac-plt along with BIND_NOW, the 
>>>> linker can choose to ignore the pac-plt directive and use smaller 
>>>> PLTs without compromising on security,
>>>> 2) For BTI, the linker must also check for the 
>>>> GNU_PROPERTY_AARCH64_FEATURE_1_BTI in its input. If all inputs have 
>>>> GNU_PROPERTY_AARCH64_FEATURE_1_BTI, the final output will also be 
>>>> marked as such. The PLT should also be protected with a BTI PLT in 
>>>> this case. Thus even if there is no linker option to use BTI PLT, 
>>>> the linker
>>>> should be able to use them depending on the NOTE section. The user 
>>>> can use the linker option --bti, to make sure that their intention 
>>>> of having all input objects (and hence the output) marked with BTI 
>>>> is not disrupted by any stray objects as this option will warn about 
>>>> it.
>>>>
>>>>
>>>> The following patches implement these changes as follows:
>>>> [1/4] Add support for GNU PROPERTIES in AArch64 for BTI and PAC:
>>>> [2/4] Add --bti-nowarn to enable BTI without warning and to select 
>>>> BTI enabled PLTs
>>>> [3/4] Add --bti to enable BTI and select BTI enabled PLTs but also 
>>>> warn for missing NOTE sections.
>>>> [4/4] Add --pac-plt to enable PLTs protected with PAC.
>>>>
>>>> This is my first time making such intrusive changes to the linker. 
>>>> Please be kind :P
>>>>
>>>> Thanks
>>>> Sudi
>>>
>>> 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 
>>>
>>>
>>> Build and regression tests all pass on aarch64-none-linux-gnu and
>>> new tests are added.
>>>
>>> Is this ok for trunk?
>>>
>>> Thanks
>>> Sudi
>>>
>>> *** bfd/ChangeLog ***
>>>
>>> 2019-xx-xx  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-xx-xx  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-xx-xx  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-xx-xx  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.
>>
>> This is part of the patch series to add support for BTI and
>> PAC in AArch64 linker.
>>
>> 1) This patch adds a new ld command line option: --bti-nowarn.
>> In the presence of this option, the linker enables BTI with the
>> GNU_PROPERTY_AARCH64_FEATURE_1_BTI feature. This gives no warning
>> in case of missing gnu notes for BTI in inputs.
>> 2) It also defines a new set of BTI enabled PLTs. These are used either
>> when all the inputs are marked with GNU_PROPERTY_AARCH64_FEATURE_1_BTI
>> or when the new --bti-nowarn option is used. This required adding new
>> fields in elf_aarch64_link_hash_table so that we could make the PLT
>> related information more generic.
>> 3) It also defines a dynamic tag DT_AARCH64_BTI_PLT. The linker uses
>> this whenever it picks BTI enabled PLTs.
>> 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 
>>
>>
>> Build and regression tests all pass on aarch64-none-linux-gnu and
>> new tests are added.
>>
>> Is this ok for trunk?
>>
>> Thanks
>> Sudi
>>
>> *** bfd/ChangeLog ***
>>
>> 2019-xx-xx  Sudakshina Das  <sudi.das@arm.com>
>>          Szabolcs Nagy  <szabolcs.nagy@arm.com>
>>
>>      * bfd-in.h (aarch64_plt_type, aarch64_enable_bti_type): New.
>>      (aarch64_bti_pac_info): New.
>>      (bfd_elf64_aarch64_set_options): Add aarch64_bti_pac_info argument.
>>      (bfd_elf32_aarch64_set_options): Likewise.
>>      * bfd-in2.h: Regenerate
>>      * elfnn-aarch64.c (PLT_BTI_ENTRY_SIZE): New.
>>      (PLT_BTI_SMALL_ENTRY_SIZE, PLT_BTI_TLSDESC_ENTRY_SIZE): New.
>>      (elfNN_aarch64_small_plt0_bti_entry): New.
>>      (elfNN_aarch64_small_plt_bti_entry): New.
>>      (elfNN_aarch64_tlsdesc_small_plt_bti_entry): New.
>>      (elf_aarch64_obj_tdata): Add no_enable_bti_warn and plt_type fields.
>>      (elf_aarch64_link_hash_table): Add plt0_entry, plt_entry and
>>      tlsdesc_plt_entry_size fields.
>>      (elfNN_aarch64_link_hash_table_create): Initialise the new fields.
>>      (setup_plt_values): New helper function.
>>      (bfd_elfNN_aarch64_set_options): Use new bp_info to set plt sizes 
>> and
>>      bti enable type.
>>      (elfNN_aarch64_allocate_dynrelocs): Use new size members instead of
>>      fixed macros.
>>      (elfNN_aarch64_size_dynamic_sections): Likewise and add checks.
>>      (elfNN_aarch64_create_small_pltn_entry): Use new generic pointers
>>      to plt stubs instead of fixed ones and update filling them according
>>      to the need for bti.
>>      (elfNN_aarch64_init_small_plt0_entry): Likewise.
>>      (elfNN_aarch64_finish_dynamic_sections): Likewise.
>>      (get_plt_type, elfNN_aarch64_get_synthetic_symtab): New.
>>      (elfNN_aarch64_plt_sym_val): Update size accordingly.
>>      (elfNN_aarch64_link_setup_gnu_properties): Set up plts if BTI GNU 
>> NOTE
>>      is set.
>>      (bfd_elfNN_get_synthetic_symtab): Define.
>>
>> *** binutils/ChangeLog ***
>>
>> 2019-xx-xx  Sudakshina Das  <sudi.das@arm.com>
>>          Szabolcs Nagy  <szabolcs.nagy@arm.com>
>>
>>      * readelf.c (get_aarch64_dynamic_type): New.
>>      (get_dynamic_type): Use above for EM_AARCH64.
>>      (dynamic_section_aarch64_val): New.
>>      (process_dynamic_section): Use above for EM_AARCH64.
>>
>> *** include/ChangeLog ***
>>
>> 2019-xx-xx  Sudakshina Das  <sudi.das@arm.com>
>>          Szabolcs Nagy  <szabolcs.nagy@arm.com>
>>
>>      * elf/aarch64.h (DT_AARCH64_BTI_PLT): New.
>>
>> *** ld/ChangeLog ***
>>
>> 2019-xx-xx  Sudakshina Das  <sudi.das@arm.com>
>>          Szabolcs Nagy  <szabolcs.nagy@arm.com>
>>
>>      * NEWS: Document --bti-nowarn.
>>      * emultempl/aarch64elf.em (plt_type, bti_type, 
>> OPTION_BTI_NOWARN): New.
>>      (PARSE_AND_LIST_SHORTOPTS, PARSE_AND_LIST_OPTIONS): Add bti-nowarn.
>>      (PARSE_AND_LIST_ARGS_CASES): Handle OPTION_BTI_NOWARN.
>>      * testsuite/ld-aarch64/aarch64-elf.exp: Add all the tests below.
>>      * testsuite/ld-aarch64/bti-plt-1.d: New test.
>>      * testsuite/ld-aarch64/bti-plt-1.s: New test.
>>      * testsuite/ld-aarch64/bti-plt-2.d: New test.
>>      * testsuite/ld-aarch64/bti-plt-3.d: New test.
>>      * testsuite/ld-aarch64/bti-plt-4.d: New test.
>>      * testsuite/ld-aarch64/bti-plt-5.d: New test.
>>      * testsuite/ld-aarch64/bti-plt-so.s: New test.
>>      * testsuite/ld-aarch64/bti-plt.ld: New test.
> 
> This is part of the patch series to add support for BTI and
> PAC in AArch64 linker.
> 
> This patch adds a new ld command line option: --bti.
> In the presence of this option, the linker enables BTI with the
> GNU_PROPERTY_AARCH64_FEATURE_1_BTI feature. It also uses the BTI
> enabled PLTs and marks with DT_AARCH64_BTI_PLT. This also gives a
> warning in case of missing gnu notes for BTI in inputs.
> 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 
> 
> 
> Build and regression tests all pass on aarch64-none-linux-gnu and
> new tests are added.
> 
> Is this ok for trunk?
> 
> Thanks
> Sudi
> 
> *** bfd/ChangeLog ***
> 
> 2019-xx-xx  Sudakshina Das  <sudi.das@arm.com>
> 
>      * elfnn-aarch64.c (elfNN_aarch64_merge_gnu_properties): Give out
>      warning with --bti and mising BTI NOTE SECTION.
> 
> *** ld/ChangeLog ***
> 
> 2019-xx-xx  Sudakshina Das  <sudi.das@arm.com>
> 
>      * NEWS: Document --bti.
>      * emultempl/aarch64elf.em (OPTION_BTI_WARN): Define.
>      (PARSE_AND_LIST_LONGOPTS, PARSE_AND_LIST_OPTIONS): Add --bti.
>      (PARSE_AND_LIST_ARGS_CASES): Handle OPTION_BTI_WARN.
>      * testsuite/ld-aarch64/aarch64-elf.exp: Add below tests.
>      * testsuite/ld-aarch64/bti-plt-6.d: New test.
>      * testsuite/ld-aarch64/bti-plt-7.d: New test.

This is part of the patch series to add support for BTI and
PAC in AArch64 linker.

1) This patch adds new definitions of PAC enabled PLTs
and both BTI and PAC enabled PLTs.
2) It also defines the new dynamic tag DT_AARCH64_PAC_PLT
for the PAC enabled PLTs.
3) This patch adds a new ld command line option: --pac-plt.
In the presence of this option, the linker uses the PAC
enabled PLTs and marks with DT_AARCH64_PAC_PLT.
4) In case both BTI and PAC are enabled the linker should
pick PLTs enabled with both and also use dynamic tags for both.
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

Build and regression tests all pass on aarch64-none-linux-gnu and
new tests are added.

Is this ok for trunk?

Thanks
Sudi

*** bfd/ChangeLog ***

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

	* elfnn-aarch64.c (PLT_PAC_ENTRY_SIZE, PLT_PAC_SMALL_ENTRY_SIZE): New.
	(PLT_BTI_PAC_ENTRY_SIZE, PLT_BTI_PAC_SMALL_ENTRY_SIZE): New.
	(setup_plt_values): Account for PAC or PAC and BTI enabled PLTs.
	(elfNN_aarch64_size_dynamic_sections): Add checks for PLT_BTI_PAC
	and PLT_PAC_PLT.
	(elfNN_aarch64_finish_dynamic_sections): Account for PLT_BTI_PAC.
	(get_plt_type): Add case for DT_AARCH64_PAC_PLT.
	(elfNN_aarch64_plt_sym_val): Add cases for PLT_BTI_PAC and PLT_PAC.

*** binutils/ChangeLog ***

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

	* readelf.c (get_aarch64_dynamic_type): Add case for
	DT_AARCH64_PAC_PLT.
	(dynamic_section_aarch64_val): Likewise.

*** include/ChangeLog ***

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

	* elf/aarch64.h (DT_AARCH64_PAC_PLT): New.

*** ld/ChangeLog ***

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

	* NEWS: Document --pac-plt.
	* emultempl/aarch64elf.em (OPTION_PAC_PLT): New.
	(PARSE_AND_LIST_LONGOPTS, PARSE_AND_LIST_OPTIONS): Add pac-plt.
	(PARSE_AND_LIST_ARGS_CASES): Handle OPTION_PAC_PLT.
	* testsuite/ld-aarch64/aarch64-elf.exp: Add the following tests.
	* testsuite/ld-aarch64/bti-pac-plt-1.d: New test.
	* testsuite/ld-aarch64/bti-pac-plt-2.d: New test.
	* testsuite/ld-aarch64/pac-plt-1.d: New test.
	* testsuite/ld-aarch64/pac-plt-2.d: New test.

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: rb10240.patch --]
[-- Type: text/x-patch; name="rb10240.patch", Size: 16248 bytes --]

diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c
index 047ba431f94446e44f54b8cad7b2c83c7a10dba6..773a028eea2f6dfd8ec4fbafaf6322095e8bcb86 100644
--- a/bfd/elfnn-aarch64.c
+++ b/bfd/elfnn-aarch64.c
@@ -271,6 +271,12 @@
 #define PLT_BTI_ENTRY_SIZE		(36)
 #define PLT_BTI_SMALL_ENTRY_SIZE	(20)
 #define PLT_BTI_TLSDESC_ENTRY_SIZE	(36)
+/* PLT sizes with PAC insn.  */
+#define PLT_PAC_ENTRY_SIZE		(36)
+#define PLT_PAC_SMALL_ENTRY_SIZE	(20)
+/* PLT sizes with BTI and PAC insn.  */
+#define PLT_BTI_PAC_ENTRY_SIZE		(40)
+#define PLT_BTI_PAC_SMALL_ENTRY_SIZE	(24)
 
 /* Encoding of the nop instruction.  */
 #define INSN_NOP 0xd503201f
@@ -319,6 +325,44 @@ static const bfd_byte elfNN_aarch64_small_plt0_bti_entry[PLT_BTI_ENTRY_SIZE] =
   0x1f, 0x20, 0x03, 0xd5,	/* nop */
 };
 
+static const bfd_byte elfNN_aarch64_small_plt0_pac_entry[PLT_PAC_ENTRY_SIZE] =
+{
+  0xf0, 0x7b, 0xbf, 0xa9,	/* stp x16, x30, [sp, #-16]!  */
+  0x10, 0x00, 0x00, 0x90,	/* adrp x16, (GOT+16)  */
+#if ARCH_SIZE == 64
+  0x11, 0x0A, 0x40, 0xf9,	/* ldr x17, [x16, #PLT_GOT+0x10]  */
+  0x10, 0x42, 0x00, 0x91,	/* add x16, x16,#PLT_GOT+0x10   */
+#else
+  0x11, 0x0A, 0x40, 0xb9,	/* ldr w17, [x16, #PLT_GOT+0x8]  */
+  0x10, 0x22, 0x00, 0x11,	/* add w16, w16,#PLT_GOT+0x8   */
+#endif
+  0x9f, 0x21, 0x03, 0xd5,	/* autia1716 */
+  0x20, 0x02, 0x1f, 0xd6,	/* br x17  */
+  0x1f, 0x20, 0x03, 0xd5,	/* nop */
+  0x1f, 0x20, 0x03, 0xd5,	/* nop */
+  0x1f, 0x20, 0x03, 0xd5,	/* nop */
+};
+
+static const bfd_byte
+elfNN_aarch64_small_plt0_bti_pac_entry[PLT_BTI_PAC_ENTRY_SIZE] =
+{
+  0x5f, 0x24, 0x03, 0xd5,	/* bti c.  */
+  0xf0, 0x7b, 0xbf, 0xa9,	/* stp x16, x30, [sp, #-16]!  */
+  0x10, 0x00, 0x00, 0x90,	/* adrp x16, (GOT+16)  */
+#if ARCH_SIZE == 64
+  0x11, 0x0A, 0x40, 0xf9,	/* ldr x17, [x16, #PLT_GOT+0x10]  */
+  0x10, 0x42, 0x00, 0x91,	/* add x16, x16,#PLT_GOT+0x10   */
+#else
+  0x11, 0x0A, 0x40, 0xb9,	/* ldr w17, [x16, #PLT_GOT+0x8]  */
+  0x10, 0x22, 0x00, 0x11,	/* add w16, w16,#PLT_GOT+0x8   */
+#endif
+  0x9f, 0x21, 0x03, 0xd5,	/* autia1716 */
+  0x20, 0x02, 0x1f, 0xd6,	/* br x17  */
+  0x1f, 0x20, 0x03, 0xd5,	/* nop */
+  0x1f, 0x20, 0x03, 0xd5,	/* nop */
+  0x1f, 0x20, 0x03, 0xd5,	/* nop */
+};
+
 /* Per function entry in a procedure linkage table looks like this
    if the distance between the PLTGOT and the PLT is < 4GB use
    these PLT entries.  Use BTI versions of the PLTs when enabled.  */
@@ -351,6 +395,37 @@ elfNN_aarch64_small_plt_bti_entry[PLT_BTI_SMALL_ENTRY_SIZE] =
 };
 
 static const bfd_byte
+elfNN_aarch64_small_plt_pac_entry[PLT_PAC_SMALL_ENTRY_SIZE] =
+{
+  0x10, 0x00, 0x00, 0x90,	/* adrp x16, PLTGOT + n * 8  */
+#if ARCH_SIZE == 64
+  0x11, 0x02, 0x40, 0xf9,	/* ldr x17, [x16, PLTGOT + n * 8] */
+  0x10, 0x02, 0x00, 0x91,	/* add x16, x16, :lo12:PLTGOT + n * 8  */
+#else
+  0x11, 0x02, 0x40, 0xb9,	/* ldr w17, [x16, PLTGOT + n * 4] */
+  0x10, 0x02, 0x00, 0x11,	/* add w16, w16, :lo12:PLTGOT + n * 4  */
+#endif
+  0x9f, 0x21, 0x03, 0xd5,	/* autia1716 */
+  0x20, 0x02, 0x1f, 0xd6,	/* br x17.  */
+};
+
+static const bfd_byte
+elfNN_aarch64_small_plt_bti_pac_entry[PLT_BTI_PAC_SMALL_ENTRY_SIZE] =
+{
+  0x5f, 0x24, 0x03, 0xd5,	/* bti c.  */
+  0x10, 0x00, 0x00, 0x90,	/* adrp x16, PLTGOT + n * 8  */
+#if ARCH_SIZE == 64
+  0x11, 0x02, 0x40, 0xf9,	/* ldr x17, [x16, PLTGOT + n * 8] */
+  0x10, 0x02, 0x00, 0x91,	/* add x16, x16, :lo12:PLTGOT + n * 8  */
+#else
+  0x11, 0x02, 0x40, 0xb9,	/* ldr w17, [x16, PLTGOT + n * 4] */
+  0x10, 0x02, 0x00, 0x11,	/* add w16, w16, :lo12:PLTGOT + n * 4  */
+#endif
+  0x9f, 0x21, 0x03, 0xd5,	/* autia1716 */
+  0x20, 0x02, 0x1f, 0xd6,	/* br x17.  */
+};
+
+static const bfd_byte
 elfNN_aarch64_tlsdesc_small_plt_entry[PLT_TLSDESC_ENTRY_SIZE] =
 {
   0xe2, 0x0f, 0xbf, 0xa9,	/* stp x2, x3, [sp, #-16]! */
@@ -4681,7 +4756,25 @@ setup_plt_values (struct bfd_link_info *link_info,
   struct elf_aarch64_link_hash_table *globals;
   globals = elf_aarch64_hash_table (link_info);
 
-  if (plt_type == PLT_BTI)
+  if (plt_type == PLT_BTI_PAC)
+    {
+      globals->plt_header_size = PLT_BTI_PAC_ENTRY_SIZE;
+      globals->plt0_entry = elfNN_aarch64_small_plt0_bti_pac_entry;
+      globals->tlsdesc_plt_entry_size = PLT_BTI_TLSDESC_ENTRY_SIZE;
+
+      /* Only in ET_EXEC we need PLTn with BTI.  */
+      if (bfd_link_pde (link_info))
+	{
+	  globals->plt_entry_size = PLT_BTI_PAC_SMALL_ENTRY_SIZE;
+	  globals->plt_entry = elfNN_aarch64_small_plt_bti_pac_entry;
+	}
+      else
+	{
+	  globals->plt_entry_size = PLT_PAC_SMALL_ENTRY_SIZE;
+	  globals->plt_entry = elfNN_aarch64_small_plt_pac_entry;
+	}
+    }
+  else if (plt_type == PLT_BTI)
     {
       globals->plt_header_size = PLT_BTI_ENTRY_SIZE;
       globals->plt0_entry = elfNN_aarch64_small_plt0_bti_entry;
@@ -4694,6 +4787,14 @@ setup_plt_values (struct bfd_link_info *link_info,
 	  globals->plt_entry = elfNN_aarch64_small_plt_bti_entry;
 	}
     }
+  else if (plt_type == PLT_PAC)
+    {
+      globals->plt_header_size = PLT_PAC_ENTRY_SIZE;
+      globals->plt0_entry = elfNN_aarch64_small_plt0_pac_entry;
+      globals->tlsdesc_plt_entry_size = PLT_TLSDESC_ENTRY_SIZE;
+      globals->plt_entry_size = PLT_PAC_SMALL_ENTRY_SIZE;
+      globals->plt_entry = elfNN_aarch64_small_plt_pac_entry;
+    }
 }
 
 /* Set option values needed during linking.  */
@@ -9083,8 +9184,17 @@ elfNN_aarch64_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
 		  || !add_dynamic_entry (DT_TLSDESC_GOT, 0)))
 	    return FALSE;
 
-	  if ((elf_aarch64_tdata (output_bfd)->plt_type == PLT_BTI)
-	      && !add_dynamic_entry (DT_AARCH64_BTI_PLT, 0))
+	  if ((elf_aarch64_tdata (output_bfd)->plt_type == PLT_BTI_PAC)
+	      && (!add_dynamic_entry (DT_AARCH64_BTI_PLT, 0)
+		  || !add_dynamic_entry (DT_AARCH64_PAC_PLT, 0)))
+	    return FALSE;
+
+	  else if ((elf_aarch64_tdata (output_bfd)->plt_type == PLT_BTI)
+		   && !add_dynamic_entry (DT_AARCH64_BTI_PLT, 0))
+	    return FALSE;
+
+	  else if ((elf_aarch64_tdata (output_bfd)->plt_type == PLT_PAC)
+		   && !add_dynamic_entry (DT_AARCH64_PAC_PLT, 0))
 	    return FALSE;
 	}
 
@@ -9610,7 +9720,7 @@ elfNN_aarch64_finish_dynamic_sections (bfd *output_bfd,
 	  htab->tlsdesc_plt_entry_size = PLT_TLSDESC_ENTRY_SIZE;
 
 	  aarch64_plt_type type = elf_aarch64_tdata (output_bfd)->plt_type;
-	  if (type == PLT_BTI)
+	  if (type == PLT_BTI || type == PLT_BTI_PAC)
 	    {
 	      entry = elfNN_aarch64_tlsdesc_small_plt_bti_entry;
 	      htab->tlsdesc_plt_entry_size = PLT_BTI_TLSDESC_ENTRY_SIZE;
@@ -9750,7 +9860,11 @@ get_plt_type (bfd *abfd)
       switch (tag)
 	{
 	case DT_AARCH64_BTI_PLT:
-	  ret = PLT_BTI;
+	  ret |= PLT_BTI;
+	  break;
+
+	case DT_AARCH64_PAC_PLT:
+	  ret |= PLT_PAC;
 	  break;
 
 	default: break;
@@ -9783,12 +9897,26 @@ elfNN_aarch64_plt_sym_val (bfd_vma i, const asection *plt,
   size_t plt0_size = PLT_ENTRY_SIZE;
   size_t pltn_size = PLT_SMALL_ENTRY_SIZE;
 
-  if (elf_aarch64_tdata (plt->owner)->plt_type == PLT_BTI)
+  if (elf_aarch64_tdata (plt->owner)->plt_type == PLT_BTI_PAC)
+    {
+      plt0_size = PLT_BTI_PAC_ENTRY_SIZE;
+      if (elf_elfheader (plt->owner)->e_type == ET_EXEC)
+	pltn_size = PLT_BTI_PAC_SMALL_ENTRY_SIZE;
+      else
+	pltn_size = PLT_PAC_SMALL_ENTRY_SIZE;
+    }
+  else if (elf_aarch64_tdata (plt->owner)->plt_type == PLT_BTI)
     {
       plt0_size = PLT_BTI_ENTRY_SIZE;
       if (elf_elfheader (plt->owner)->e_type == ET_EXEC)
 	pltn_size = PLT_BTI_SMALL_ENTRY_SIZE;
     }
+  else if (elf_aarch64_tdata (plt->owner)->plt_type == PLT_PAC)
+    {
+      plt0_size = PLT_PAC_ENTRY_SIZE;
+      pltn_size = PLT_PAC_SMALL_ENTRY_SIZE;
+    }
+
   return plt->vma + plt0_size + i * pltn_size;
 }
 
diff --git a/binutils/readelf.c b/binutils/readelf.c
index f4775b439fc6a14a14699c88af3fe5f07648352e..5a9d9ff433d5438e073e871b9c92d307d9f279d3 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -1803,6 +1803,7 @@ get_aarch64_dynamic_type (unsigned long type)
   switch (type)
     {
     case DT_AARCH64_BTI_PLT:  return "AARCH64_BTI_PLT";
+    case DT_AARCH64_PAC_PLT:  return "AARCH64_PAC_PLT";
     default:
       return NULL;
     }
@@ -9364,6 +9365,7 @@ dynamic_section_aarch64_val (Elf_Internal_Dyn * entry)
   switch (entry->d_tag)
     {
     case DT_AARCH64_BTI_PLT:
+    case DT_AARCH64_PAC_PLT:
       break;
     default:
       print_vma (entry->d_un.d_ptr, PREFIX_HEX);
diff --git a/include/elf/aarch64.h b/include/elf/aarch64.h
index b86a1006297891d38f55f0c29d0ac51056b0c6e3..44665476265b8d20c59343dcbafc87766a5444c0 100644
--- a/include/elf/aarch64.h
+++ b/include/elf/aarch64.h
@@ -37,6 +37,7 @@
 						in the input to a link step.  */
 /* Processor specific dynamic array tags.  */
 #define DT_AARCH64_BTI_PLT	(DT_LOPROC + 1)
+#define DT_AARCH64_PAC_PLT	(DT_LOPROC + 3)
 
 /* Relocation types.  */
 
diff --git a/ld/NEWS b/ld/NEWS
index ec234dfeb0869a407ee266b476cfdb956de8ceaf..b5ffffa7957e39e03003171b77c8f816273cf465 100644
--- a/ld/NEWS
+++ b/ld/NEWS
@@ -17,6 +17,8 @@ Changes in 2.33:
   on output while warning about missing GNU_PROPERTY_AARCH64_FEATURE_1_BTI
   on inputs and pick BTI enables PLTs.
 
+* Add --pac-plt for AArch64 to pick PAC enabled PLTs.
+
 Changes in 2.32:
 
 * Report property change in linker map file when merging GNU properties.
diff --git a/ld/emultempl/aarch64elf.em b/ld/emultempl/aarch64elf.em
index c2db3e9e531930f0659197219369da1ddb04275c..520d621f4eef94956de2f24ccd39917083279a6c 100644
--- a/ld/emultempl/aarch64elf.em
+++ b/ld/emultempl/aarch64elf.em
@@ -374,6 +374,7 @@ PARSE_AND_LIST_PROLOGUE='
 #define OPTION_NO_APPLY_DYNAMIC_RELOCS	315
 #define OPTION_BTI_NOWARN		316
 #define OPTION_BTI_WARN			317
+#define OPTION_PAC_PLT			318
 '
 
 PARSE_AND_LIST_SHORTOPTS=p
@@ -389,6 +390,7 @@ PARSE_AND_LIST_LONGOPTS='
   { "no-apply-dynamic-relocs", no_argument, NULL, OPTION_NO_APPLY_DYNAMIC_RELOCS},
   { "bti-nowarn", no_argument, NULL, OPTION_BTI_NOWARN},
   { "bti", no_argument, NULL, OPTION_BTI_WARN},
+  { "pac-plt", no_argument, NULL, OPTION_PAC_PLT},
 '
 
 PARSE_AND_LIST_OPTIONS='
@@ -411,6 +413,7 @@ PARSE_AND_LIST_OPTIONS='
   fprintf (file, _("  --no-apply-dynamic-relocs    Do not apply link-time values for dynamic relocations\n"));
   fprintf (file, _("  --bti-nowarn                 Turn on Branch Target Identification mechanism and generate PLTs with BTI. Generate no warnings for missing BTI on inputs\n"));
   fprintf (file, _("  --bti                        Turn on Branch Target Identification mechanism and generate PLTs with BTI. Generate warnings for missing BTI on inputs\n"));
+  fprintf (file, _("  --pac-plt                    Protect PLTs with Pointer Authentication.\n"));
 '
 
 PARSE_AND_LIST_ARGS_CASES='
@@ -452,6 +455,10 @@ PARSE_AND_LIST_ARGS_CASES='
       bti_type = BTI_WARN;
       break;
 
+    case OPTION_PAC_PLT:
+      plt_type |= PLT_PAC;
+      break;
+
     case OPTION_STUBGROUP_SIZE:
       {
 	const char *end;
diff --git a/ld/testsuite/ld-aarch64/aarch64-elf.exp b/ld/testsuite/ld-aarch64/aarch64-elf.exp
index 906534b230c8905fb97a6739e1c1411683455fe3..12c2d97d53770e886bb913e19aef996a64fc1805 100644
--- a/ld/testsuite/ld-aarch64/aarch64-elf.exp
+++ b/ld/testsuite/ld-aarch64/aarch64-elf.exp
@@ -402,3 +402,8 @@ run_dump_test "bti-plt-4"
 run_dump_test "bti-plt-5"
 run_dump_test "bti-plt-6"
 run_dump_test "bti-plt-7"
+
+run_dump_test "pac-plt-1"
+run_dump_test "pac-plt-2"
+run_dump_test "bti-pac-plt-1"
+run_dump_test "bti-pac-plt-2"
diff --git a/ld/testsuite/ld-aarch64/bti-pac-plt-1.d b/ld/testsuite/ld-aarch64/bti-pac-plt-1.d
new file mode 100644
index 0000000000000000000000000000000000000000..feebb971228edaf9484782d4e44e59733e88b04a
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/bti-pac-plt-1.d
@@ -0,0 +1,34 @@
+#source: bti-plt-1.s
+#as: -mabi=lp64
+#ld: -shared --bti --pac-plt -T bti-plt.ld
+#objdump: -dr -j .plt
+
+[^:]*: *file format elf64-.*aarch64
+
+Disassembly of section \.plt:
+
+[0-9a-f]+ <.*>:
+.*:	d503245f 	bti	c
+.*:	a9bf7bf0 	stp	x16, x30, \[sp, #-16\]!
+.*:	90000090 	adrp	x16, 28000 <_GLOBAL_OFFSET_TABLE_>
+.*:	f9400e11 	ldr	x17, \[x16, #24\]
+.*:	91006210 	add	x16, x16, #0x18
+.*:	d503219f 	autia1716
+.*:	d61f0220 	br	x17
+.*:	d503201f 	nop
+.*:	d503201f 	nop
+.*:	d503201f 	nop
+
+[0-9a-f]+ <.*>:
+.*:	90000090 	adrp	x16, 28000 <_GLOBAL_OFFSET_TABLE_>
+.*:	f9401211 	ldr	x17, \[x16, #32\]
+.*:	91008210 	add	x16, x16, #0x20
+.*:	d503219f 	autia1716
+.*:	d61f0220 	br	x17
+
+[0-9a-f]+ <.*>:
+.*:	90000090 	adrp	x16, 28000 <_GLOBAL_OFFSET_TABLE_>
+.*:	f9401611 	ldr	x17, \[x16, #40\]
+.*:	9100a210 	add	x16, x16, #0x28
+.*:	d503219f 	autia1716
+.*:	d61f0220 	br	x17
diff --git a/ld/testsuite/ld-aarch64/bti-pac-plt-2.d b/ld/testsuite/ld-aarch64/bti-pac-plt-2.d
new file mode 100644
index 0000000000000000000000000000000000000000..2d9fab8101b129b8ebfef1a2abc2e01b98bf06e5
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/bti-pac-plt-2.d
@@ -0,0 +1,36 @@
+#source: bti-plt-1.s
+#as: -mabi=lp64
+#ld: --bti --pac-plt -e _start -T bti-plt.ld -L./tmpdir -lbti-plt-so
+#objdump: -dr -j .plt
+
+[^:]*: *file format elf64-.*aarch64
+
+Disassembly of section \.plt:
+
+[0-9]+ <.*>:
+.*:	d503245f 	bti	c
+.*:	a9bf7bf0 	stp	x16, x30, \[sp, #-16\]!
+.*:	90000090 	adrp	x16, 28000 <_GLOBAL_OFFSET_TABLE_>
+.*:	f9400e11 	ldr	x17, \[x16, #24\]
+.*:	91006210 	add	x16, x16, #0x18
+.*:	d503219f 	autia1716
+.*:	d61f0220 	br	x17
+.*:	d503201f 	nop
+.*:	d503201f 	nop
+.*:	d503201f 	nop
+
+[0-9]+ <.*>:
+.*:	d503245f 	bti	c
+.*:	90000090 	adrp	x16, 28000 <_GLOBAL_OFFSET_TABLE_>
+.*:	f9401211 	ldr	x17, \[x16, #32\]
+.*:	91008210 	add	x16, x16, #0x20
+.*:	d503219f 	autia1716
+.*:	d61f0220 	br	x17
+
+[0-9]+ <.*>:
+.*:	d503245f 	bti	c
+.*:	90000090 	adrp	x16, 28000 <_GLOBAL_OFFSET_TABLE_>
+.*:	f9401611 	ldr	x17, \[x16, #40\]
+.*:	9100a210 	add	x16, x16, #0x28
+.*:	d503219f 	autia1716
+.*:	d61f0220 	br	x17
diff --git a/ld/testsuite/ld-aarch64/pac-plt-1.d b/ld/testsuite/ld-aarch64/pac-plt-1.d
new file mode 100644
index 0000000000000000000000000000000000000000..09a07f907e5f4ddedc628f9474713ddb696de2a0
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/pac-plt-1.d
@@ -0,0 +1,33 @@
+#source: bti-plt-1.s
+#as: -mabi=lp64
+#ld: -shared --pac-plt -T bti-plt.ld
+#objdump: -dr -j .plt
+
+[^:]*: *file format elf64-.*aarch64
+
+Disassembly of section \.plt:
+
+[0-9]+ <.*>:
+.*:	a9bf7bf0 	stp	x16, x30, \[sp, #-16\]!
+.*:	90000090 	adrp	x16, 28000 <_GLOBAL_OFFSET_TABLE_>
+.*:	f9400e11 	ldr	x17, \[x16, #24\]
+.*:	91006210 	add	x16, x16, #0x18
+.*:	d503219f 	autia1716
+.*:	d61f0220 	br	x17
+.*:	d503201f 	nop
+.*:	d503201f 	nop
+.*:	d503201f 	nop
+
+[0-9]+ <.*>:
+.*:	90000090 	adrp	x16, 28000 <_GLOBAL_OFFSET_TABLE_>
+.*:	f9401211 	ldr	x17, \[x16, #32\]
+.*:	91008210 	add	x16, x16, #0x20
+.*:	d503219f 	autia1716
+.*:	d61f0220 	br	x17
+
+[0-9]+ <.*>:
+.*:	90000090 	adrp	x16, 28000 <_GLOBAL_OFFSET_TABLE_>
+.*:	f9401611 	ldr	x17, \[x16, #40\]
+.*:	9100a210 	add	x16, x16, #0x28
+.*:	d503219f 	autia1716
+.*:	d61f0220 	br	x17
diff --git a/ld/testsuite/ld-aarch64/pac-plt-2.d b/ld/testsuite/ld-aarch64/pac-plt-2.d
new file mode 100644
index 0000000000000000000000000000000000000000..42bfdca6218d191de846ce482f23b5f627e55034
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/pac-plt-2.d
@@ -0,0 +1,24 @@
+#source: tls-desc-ie.s
+#ld: -shared --pac-plt -T bti-plt.ld
+#objdump: -dr -j .plt
+#...
+Disassembly of section .plt:
+
+0000000000018000 \<.plt\>:
+.*:	a9bf7bf0 	stp	x16, x30, \[sp, #-16\]!
+.*:	90000090 	adrp	x16, 28000 <_GLOBAL_OFFSET_TABLE_>
+.*:	f9401a11 	ldr	x17, \[x16, #48\]
+.*:	9100c210 	add	x16, x16, #0x30
+.*:	d503219f 	autia1716
+.*:	d61f0220 	br	x17
+.*:	d503201f 	nop
+.*:	d503201f 	nop
+.*:	d503201f 	nop
+
+
+0000000000018024 \<__tls_get_addr@plt\>:
+.*:	90000090 	adrp	x16, 28000 <_GLOBAL_OFFSET_TABLE_>
+.*:	f9401e11 	ldr	x17, \[x16, #56\]
+.*:	9100e210 	add	x16, x16, #0x38
+.*:	d503219f 	autia1716
+.*:	d61f0220 	br	x17

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

* Re: [PATCH, BFD, LD, AArch64, 0/4] Add support for AArch64 BTI and PAC in the linker
  2019-03-06 10:26 [PATCH, BFD, LD, AArch64, 0/4] Add support for AArch64 BTI and PAC in the linker Sudakshina Das
  2019-03-06 10:31 ` [PATCH, BFD, LD, AArch64, 1/4] Add support for GNU PROPERTIES in AArch64 for BTI and PAC Sudakshina Das
@ 2019-03-07 12:37 ` Nick Clifton
  2019-03-07 14:28   ` Sudakshina Das
  1 sibling, 1 reply; 22+ messages in thread
From: Nick Clifton @ 2019-03-07 12:37 UTC (permalink / raw)
  To: Sudakshina Das, binutils; +Cc: nd, Richard Earnshaw, Ramana Radhakrishnan

Hi Sudi,

  [This is me being kind :-) ...]

> We introduce a new set of command line options for the linker in order 
> to support the correct PLTs

Are you also planning on creating patches for GOLD and LLD to support
these features ?  If so, it would probably be best to submit them at
the same time as the BFD linker patches.

Presumably there will also need to be a patch to the loader.  Has this
patch been prepared ?  (Obviously we cannot approve such a patch here,
but it would be good if this patch series included a link to the glibc
patch, and vice versa).


>   - GNU_PROPERTY_AARCH64_FEATURE_1_PAC (We have only reserved this bit
>      for now.)

Why is this bit only reserved at the moment ?   Shouldn't the linker
patches be treating this bit in a similar way to the GNU_PROPERTY_AARCH64_FEATRUE_1_BTI
bit ?


> 3)--bti-nowarn - Same as above but does not emit any warnings.

I am not clear about the purpose/need for this option.  According to this:

> 2) For BTI, the linker must also check for the 
> GNU_PROPERTY_AARCH64_FEATURE_1_BTI in its input. If all inputs have 
> GNU_PROPERTY_AARCH64_FEATURE_1_BTI, the final output will also be marked 
> as such. The PLT should also be protected with a BTI PLT in this case. 
> Thus even if there is no linker option to use BTI PLT, the linker
> should be able to use them depending on the NOTE section. The user can 
> use the linker option --bti, to make sure that their intention of having 
> all input objects (and hence the output) marked with BTI is not 
> disrupted by any stray objects as this option will warn about it.

The linker will automatically set the BTI tag if all of the inputs have
the BTI note, and, by default, will not warn if one or more of the inputs
do not have the note. So what does the --bti-nowarn option do ?

[As an aside, do you think that there might be a need for a --bti-disable
option, which would stop the setting of the BTI tag, even if all of the
input objects have the BTI note ?  I am not sure myself, but I suppose in
theory there might be some reason to want this].


> Details of these can be found in the new AArch64 ELF documentation:
> https://developer.arm.com/docs/ihi0056/latest/elf-for-the-arm-64-bit-architecture-aarch64-abi-2018q4

It would be nice if this document was available as a PDF or something
similar, so that it could be downloaded and used offline.

The document does not appear to specify what the loader should do if
there is more than one GNU_PROPERTY_AARCh64_FEATURE_1_AND note in an
executable.  (Which would be there if the executable had been linked
by a linker that does not know how to merge multiple GNU_PROPERTY notes).


Have you considered how these new PLTs will affect other tools that
inspect them ?  For example ltrace or glibc's la_pltenter() and la_pltexit()
functions ?

OK, that's it for general comments.  I will reserve patch specific comments
for each individual patch.

Cheers
  Nick

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

* Re: [PATCH, BFD, LD, AArch64, 0/4] Add support for AArch64 BTI and PAC in the linker
  2019-03-07 12:37 ` [PATCH, BFD, LD, AArch64, 0/4] Add support for AArch64 BTI and PAC in the linker Nick Clifton
@ 2019-03-07 14:28   ` Sudakshina Das
  2019-03-07 15:26     ` Peter Smith
  2019-03-07 15:33     ` Nick Clifton
  0 siblings, 2 replies; 22+ messages in thread
From: Sudakshina Das @ 2019-03-07 14:28 UTC (permalink / raw)
  To: nickc, binutils; +Cc: nd, Richard Earnshaw, Ramana Radhakrishnan, peter.smith

Hi Nick

On 07/03/2019 12:37, Nick Clifton wrote:
> Hi Sudi,
> 
>    [This is me being kind :-) ...]

Thank you :)
> 
>> We introduce a new set of command line options for the linker in order
>> to support the correct PLTs
> 
> Are you also planning on creating patches for GOLD and LLD to support
> these features ?  If so, it would probably be best to submit them at
> the same time as the BFD linker patches.

I am CC'ing Peter who would be better able to answer about LLD and GOLD.
> 
> Presumably there will also need to be a patch to the loader.  Has this
> patch been prepared ?  (Obviously we cannot approve such a patch here,
> but it would be good if this patch series included a link to the glibc
> patch, and vice versa).
> 

Yes, I am currently trying to get the glibc patches on the mailing list 
soon but they need some co-ordination with the kernel patches!

> 
>>    - GNU_PROPERTY_AARCH64_FEATURE_1_PAC (We have only reserved this bit
>>       for now.)
> 
> Why is this bit only reserved at the moment ?   Shouldn't the linker
> patches be treating this bit in a similar way to the GNU_PROPERTY_AARCH64_FEATRUE_1_BTI
> bit ?

Sorry I should have been clearer with this. The linker does treat it in 
the similar way in collecting the input note section and marking the 
output note section where applicable. The loader however does not do 
much with it.

> 
> 
>> 3)--bti-nowarn - Same as above but does not emit any warnings.
> 
> I am not clear about the purpose/need for this option.  According to this:
> 
>> 2) For BTI, the linker must also check for the
>> GNU_PROPERTY_AARCH64_FEATURE_1_BTI in its input. If all inputs have
>> GNU_PROPERTY_AARCH64_FEATURE_1_BTI, the final output will also be marked
>> as such. The PLT should also be protected with a BTI PLT in this case.
>> Thus even if there is no linker option to use BTI PLT, the linker
>> should be able to use them depending on the NOTE section. The user can
>> use the linker option --bti, to make sure that their intention of having
>> all input objects (and hence the output) marked with BTI is not
>> disrupted by any stray objects as this option will warn about it.
> 
> The linker will automatically set the BTI tag if all of the inputs have
> the BTI note, and, by default, will not warn if one or more of the inputs
> do not have the note. So what does the --bti-nowarn option do ?

The linker should automatically collect all note sections and mark the 
output with BTI if ALL the inputs have BTI in them. However, in this 
default behavior, if there is any stray objects without the BTI note 
section, the linker will silently remove the BTI note section from the 
output. Both the linker command line options are for users to specify 
that they want the output to be marked with BTI. The difference is that 
--bti will warn about the stray object and --bti-nowarn will not warn.

> 
> [As an aside, do you think that there might be a need for a --bti-disable
> option, which would stop the setting of the BTI tag, even if all of the
> input objects have the BTI note ?  I am not sure myself, but I suppose in
> theory there might be some reason to want this].

Yes maybe --bti-disable option also makes sense. I will give it some 
more thought on a use case for it.

> 
> 
>> Details of these can be found in the new AArch64 ELF documentation:
>> https://developer.arm.com/docs/ihi0056/latest/elf-for-the-arm-64-bit-architecture-aarch64-abi-2018q4
> 
> It would be nice if this document was available as a PDF or something
> similar, so that it could be downloaded and used offline.
> 

Unfortunately the format of the document is not in my control but I have 
expressed the need for a downloadable version.

> The document does not appear to specify what the loader should do if
> there is more than one GNU_PROPERTY_AARCh64_FEATURE_1_AND note in an
> executable.  (Which would be there if the executable had been linked
> by a linker that does not know how to merge multiple GNU_PROPERTY notes).
> 

Hmm I have not really considered that. I will get back to you soon on this.

> 
> Have you considered how these new PLTs will affect other tools that
> inspect them ?  For example ltrace or glibc's la_pltenter() and la_pltexit()
> functions ?
>

We have defined new DT_ tags which can be used as indicators of PLT 
sizes. These tools would need to add support to read these and not use 
hard coded PLT sizes.

> OK, that's it for general comments.  I will reserve patch specific comments
> for each individual patch.
> 
> Cheers
>    Nick
> 


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

* Re: [PATCH, BFD, LD, AArch64, 0/4] Add support for AArch64 BTI and PAC in the linker
  2019-03-07 14:28   ` Sudakshina Das
@ 2019-03-07 15:26     ` Peter Smith
  2019-03-07 15:35       ` Nick Clifton
  2019-03-07 15:33     ` Nick Clifton
  1 sibling, 1 reply; 22+ messages in thread
From: Peter Smith @ 2019-03-07 15:26 UTC (permalink / raw)
  To: Sudakshina Das
  Cc: nickc, binutils, nd, Richard Earnshaw, Ramana Radhakrishnan

On Thu, 7 Mar 2019 at 14:28, Sudakshina Das <Sudi.Das@arm.com> wrote:
>
> Hi Nick
>
> On 07/03/2019 12:37, Nick Clifton wrote:
> > Hi Sudi,
> >
> >    [This is me being kind :-) ...]
>
> Thank you :)
> >
> >> We introduce a new set of command line options for the linker in order
> >> to support the correct PLTs
> >
> > Are you also planning on creating patches for GOLD and LLD to support
> > these features ?  If so, it would probably be best to submit them at
> > the same time as the BFD linker patches.
>
> I am CC'ing Peter who would be better able to answer about LLD and GOLD.

I've got LLD work on my backlog at the moment. It will likely need to
be coordinated with support for Intel CET
(https://reviews.llvm.org/D58102), which introduces .note.gnu.property
to LLD. Gold is of a lower priority right now, at least for Linaro,
with the most likely outcome that it will be worked on when a project
needs it, most likely when this feature is present in platforms that
people use gold to build applications with.

> > The document does not appear to specify what the loader should do if
> > there is more than one GNU_PROPERTY_AARCh64_FEATURE_1_AND note in an
> > executable.  (Which would be there if the executable had been linked
> > by a linker that does not know how to merge multiple GNU_PROPERTY notes).
> >
>
> Hmm I have not really considered that. I will get back to you soon on this.
>

My initial thought is that if there is more than one
.note.gnu.property section in the executable then the static linker
didn't understand the section and hence we can't assume it did any of
the required actions like producing different PLT sections. Hence I
think acting as if there were no .note.gnu.property sections present
at all would be a sensible choice.

Peter

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

* Re: [PATCH, BFD, LD, AArch64, 0/4] Add support for AArch64 BTI and PAC in the linker
  2019-03-07 14:28   ` Sudakshina Das
  2019-03-07 15:26     ` Peter Smith
@ 2019-03-07 15:33     ` Nick Clifton
  2019-03-07 17:53       ` Sudakshina Das
  1 sibling, 1 reply; 22+ messages in thread
From: Nick Clifton @ 2019-03-07 15:33 UTC (permalink / raw)
  To: Sudakshina Das, binutils
  Cc: nd, Richard Earnshaw, Ramana Radhakrishnan, peter.smith

Hi Sudi,

>>> 3)--bti-nowarn - Same as above but does not emit any warnings.
>>
>> I am not clear about the purpose/need for this option.  According to this:
>>
>>> 2) For BTI, the linker must also check for the
>>> GNU_PROPERTY_AARCH64_FEATURE_1_BTI in its input. If all inputs have
>>> GNU_PROPERTY_AARCH64_FEATURE_1_BTI, the final output will also be marked
>>> as such. The PLT should also be protected with a BTI PLT in this case.
>>> Thus even if there is no linker option to use BTI PLT, the linker
>>> should be able to use them depending on the NOTE section. The user can
>>> use the linker option --bti, to make sure that their intention of having
>>> all input objects (and hence the output) marked with BTI is not
>>> disrupted by any stray objects as this option will warn about it.
>>
>> The linker will automatically set the BTI tag if all of the inputs have
>> the BTI note, and, by default, will not warn if one or more of the inputs
>> do not have the note. So what does the --bti-nowarn option do ?
> 
> The linker should automatically collect all note sections and mark the 
> output with BTI if ALL the inputs have BTI in them. However, in this 
> default behavior, if there is any stray objects without the BTI note 
> section, the linker will silently remove the BTI note section from the 
> output. Both the linker command line options are for users to specify 
> that they want the output to be marked with BTI. The difference is that 
> --bti will warn about the stray object and --bti-nowarn will not warn.

OK, so just to be clear, with --bti or --bti-nowarn the output will be
given the BTI tag *even if* some of the input files do not have the BTI note ?

This sounds like a serious potential problem.  If BTI is enabled and a
particular object file has not been built with BTI support enabled, then
won't any function calls into that object file fail ?



>> OK, that's it for general comments.  I will reserve patch specific comments
>> for each individual patch.

[These will probably be tomorrow now as I am a little bit swamped with other things today]

Cheers
  Nick

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

* Re: [PATCH, BFD, LD, AArch64, 0/4] Add support for AArch64 BTI and PAC in the linker
  2019-03-07 15:26     ` Peter Smith
@ 2019-03-07 15:35       ` Nick Clifton
  2019-03-07 15:49         ` Szabolcs Nagy
  0 siblings, 1 reply; 22+ messages in thread
From: Nick Clifton @ 2019-03-07 15:35 UTC (permalink / raw)
  To: Peter Smith, Sudakshina Das
  Cc: binutils, nd, Richard Earnshaw, Ramana Radhakrishnan

Hi Peter,

> I've got LLD work on my backlog at the moment. It will likely need to
> be coordinated with support for Intel CET

That makes sense.

>>> The document does not appear to specify what the loader should do if
>>> there is more than one GNU_PROPERTY_AARCh64_FEATURE_1_AND note in an
>>> executable.  (Which would be there if the executable had been linked
>>> by a linker that does not know how to merge multiple GNU_PROPERTY notes).

> My initial thought is that if there is more than one
> .note.gnu.property section in the executable then the static linker
> didn't understand the section and hence we can't assume it did any of
> the required actions like producing different PLT sections. Hence I
> think acting as if there were no .note.gnu.property sections present
> at all would be a sensible choice.

Agreed.  I would just like to see this clearly specified in the documentation
so that other linker maintainers know where they stand.

Cheers
  Nick


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

* Re: [PATCH, BFD, LD, AArch64, 0/4] Add support for AArch64 BTI and PAC in the linker
  2019-03-07 15:35       ` Nick Clifton
@ 2019-03-07 15:49         ` Szabolcs Nagy
  0 siblings, 0 replies; 22+ messages in thread
From: Szabolcs Nagy @ 2019-03-07 15:49 UTC (permalink / raw)
  To: nickc, Peter Smith, Sudakshina Das
  Cc: nd, binutils, Richard Earnshaw, Ramana Radhakrishnan

On 07/03/2019 15:35, Nick Clifton wrote:
>>>> The document does not appear to specify what the loader should do if
>>>> there is more than one GNU_PROPERTY_AARCh64_FEATURE_1_AND note in an
>>>> executable.  (Which would be there if the executable had been linked
>>>> by a linker that does not know how to merge multiple GNU_PROPERTY notes).
> 
>> My initial thought is that if there is more than one
>> .note.gnu.property section in the executable then the static linker
>> didn't understand the section and hence we can't assume it did any of
>> the required actions like producing different PLT sections. Hence I
>> think acting as if there were no .note.gnu.property sections present
>> at all would be a sensible choice.
> 
> Agreed.  I would just like to see this clearly specified in the documentation
> so that other linker maintainers know where they stand.

so arm decided to use the "gnu property" thing to mark elf modules.
this means the behaviour should be mostly decided by "gnu" i think.

in this case if linkers don't merge gnu property notes, that sounds
like a processor independent problem so ideally the solution would
be the same across targets. (i.e. x86_64 and aarch64 should behave
consistently)

in any case this belongs to either an os specific sysv abi
document (i.e. linux-abi maintained by H.J.Lu) or processor
specific sys v abi (arm has not published this yet) because
those describe dynamic linking behaviour. (the arm elf abi
does not cover dynamic linking)


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

* Re: [PATCH, BFD, LD, AArch64, 0/4] Add support for AArch64 BTI and PAC in the linker
  2019-03-07 15:33     ` Nick Clifton
@ 2019-03-07 17:53       ` Sudakshina Das
  2019-03-08 10:07         ` Nick Clifton
  0 siblings, 1 reply; 22+ messages in thread
From: Sudakshina Das @ 2019-03-07 17:53 UTC (permalink / raw)
  To: nickc, binutils; +Cc: nd, Richard Earnshaw, Ramana Radhakrishnan, peter.smith

Hi Nick

On 07/03/2019 15:33, Nick Clifton wrote:
> Hi Sudi,
> 
>>>> 3)--bti-nowarn - Same as above but does not emit any warnings.
>>>
>>> I am not clear about the purpose/need for this option.  According to this:
>>>
>>>> 2) For BTI, the linker must also check for the
>>>> GNU_PROPERTY_AARCH64_FEATURE_1_BTI in its input. If all inputs have
>>>> GNU_PROPERTY_AARCH64_FEATURE_1_BTI, the final output will also be marked
>>>> as such. The PLT should also be protected with a BTI PLT in this case.
>>>> Thus even if there is no linker option to use BTI PLT, the linker
>>>> should be able to use them depending on the NOTE section. The user can
>>>> use the linker option --bti, to make sure that their intention of having
>>>> all input objects (and hence the output) marked with BTI is not
>>>> disrupted by any stray objects as this option will warn about it.
>>>
>>> The linker will automatically set the BTI tag if all of the inputs have
>>> the BTI note, and, by default, will not warn if one or more of the inputs
>>> do not have the note. So what does the --bti-nowarn option do ?
>>
>> The linker should automatically collect all note sections and mark the
>> output with BTI if ALL the inputs have BTI in them. However, in this
>> default behavior, if there is any stray objects without the BTI note
>> section, the linker will silently remove the BTI note section from the
>> output. Both the linker command line options are for users to specify
>> that they want the output to be marked with BTI. The difference is that
>> --bti will warn about the stray object and --bti-nowarn will not warn.
> 
> OK, so just to be clear, with --bti or --bti-nowarn the output will be
> given the BTI tag *even if* some of the input files do not have the BTI note ?
> 

Yes
> This sounds like a serious potential problem.  If BTI is enabled and a
> particular object file has not been built with BTI support enabled, then
> won't any function calls into that object file fail ?
> 

The linker is capable of doing the right thing on its own without any 
user option. It will silently remove the BTI note on the output if there 
are objects with missing BTI note section. The user options are an 
indication of what they want, *to turn on BTI*. They can use --bti, 
where the linker will complain about the missing BTI marking and they 
can go back and check the objects that need recompiling or use 
--bti-nowarn when they are sure that even if there is any object with 
missing BTI note section it is still safe to turn on BTI (or they still 
want to turn on BTI). We think that these options would be most helpful 
in early deployment.

Sudi

> 
> 
>>> OK, that's it for general comments.  I will reserve patch specific comments
>>> for each individual patch.
> 
> [These will probably be tomorrow now as I am a little bit swamped with other things today]
> 
> Cheers
>    Nick
> 


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

* Re: [PATCH, BFD, LD, AArch64, 0/4] Add support for AArch64 BTI and PAC in the linker
  2019-03-07 17:53       ` Sudakshina Das
@ 2019-03-08 10:07         ` Nick Clifton
  2019-03-08 11:08           ` Szabolcs Nagy
  2019-03-08 11:14           ` Ramana Radhakrishnan
  0 siblings, 2 replies; 22+ messages in thread
From: Nick Clifton @ 2019-03-08 10:07 UTC (permalink / raw)
  To: Sudakshina Das, binutils
  Cc: nd, Richard Earnshaw, Ramana Radhakrishnan, peter.smith

Hi Sudi,

>> OK, so just to be clear, with --bti or --bti-nowarn the output will be
>> given the BTI tag *even if* some of the input files do not have the BTI note ?

> Yes

> can go back and check the objects that need recompiling or use 
> --bti-nowarn when they are sure that even if there is any object with 
> missing BTI note section it is still safe to turn on BTI (or they still 
> want to turn on BTI). We think that these options would be most helpful 
> in early deployment.

OK, well I get the --bti option then, but I still think that --bti-nowarn
is a mistake.  Given that --bti will only generate warnings if there are
object files without the BTI note, and warnings can be ignored, I do not
see the need for --bti-nowarn.  Plus using --bti-nowarn could potentially
cause problems if the developer forgets (or does not know) that it is 
enabled, and they end up thinking that they are creating BTI enabled 
binaries when in fact they are not.

If a developer really wants to skip the warnings they could pipe the
output from the linker through a grep that eliminates them.  Which would
have the added benefit of being more visible in the output logs of a 
complex build than a single command line option.

Cheers
  Nick


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

* Re: [PATCH, BFD, LD, AArch64, 0/4] Add support for AArch64 BTI and PAC in the linker
  2019-03-08 10:07         ` Nick Clifton
@ 2019-03-08 11:08           ` Szabolcs Nagy
  2019-03-08 11:14           ` Ramana Radhakrishnan
  1 sibling, 0 replies; 22+ messages in thread
From: Szabolcs Nagy @ 2019-03-08 11:08 UTC (permalink / raw)
  To: nickc, Sudakshina Das, binutils
  Cc: nd, Richard Earnshaw, Ramana Radhakrishnan, peter.smith

On 08/03/2019 10:07, Nick Clifton wrote:
> Hi Sudi,
> 
>>> OK, so just to be clear, with --bti or --bti-nowarn the output will be
>>> given the BTI tag *even if* some of the input files do not have the BTI note ?
> 
>> Yes
> 
>> can go back and check the objects that need recompiling or use 
>> --bti-nowarn when they are sure that even if there is any object with 
>> missing BTI note section it is still safe to turn on BTI (or they still 
>> want to turn on BTI). We think that these options would be most helpful 
>> in early deployment.
> 
> OK, well I get the --bti option then, but I still think that --bti-nowarn
> is a mistake.  Given that --bti will only generate warnings if there are
> object files without the BTI note, and warnings can be ignored, I do not
> see the need for --bti-nowarn.  Plus using --bti-nowarn could potentially
> cause problems if the developer forgets (or does not know) that it is 
> enabled, and they end up thinking that they are creating BTI enabled 
> binaries when in fact they are not.
> 
> If a developer really wants to skip the warnings they could pipe the
> output from the linker through a grep that eliminates them.  Which would
> have the added benefit of being more visible in the output logs of a 
> complex build than a single command line option.

does -z ibt warn on x86_64?

it is important to allow the user to force bti on
(a non-bti marked object file can easily be compatible
with bti, e.g if there are no indirect branches targeting
it, or somebody might just want to do runtime tests to
find out where are the problematic branches), so at least
one of --bti or --bti-nowarn should be added, it is just
convenience to have them both since there are different
use cases.

i think it's also reasonable to just have one option that
is compatible with the x86_64 behaviour.


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

* Re: [PATCH, BFD, LD, AArch64, 0/4] Add support for AArch64 BTI and PAC in the linker
  2019-03-08 10:07         ` Nick Clifton
  2019-03-08 11:08           ` Szabolcs Nagy
@ 2019-03-08 11:14           ` Ramana Radhakrishnan
  2019-03-08 11:46             ` Peter Smith
  1 sibling, 1 reply; 22+ messages in thread
From: Ramana Radhakrishnan @ 2019-03-08 11:14 UTC (permalink / raw)
  To: nickc, Sudakshina Das, binutils; +Cc: nd, Richard Earnshaw, peter.smith

On 08/03/2019 10:07, Nick Clifton wrote:
> Hi Sudi,
> 
>>> OK, so just to be clear, with --bti or --bti-nowarn the output will be
>>> given the BTI tag *even if* some of the input files do not have the BTI note ?
> 
>> Yes
> 
>> can go back and check the objects that need recompiling or use 
>> --bti-nowarn when they are sure that even if there is any object with 
>> missing BTI note section it is still safe to turn on BTI (or they still 
>> want to turn on BTI). We think that these options would be most helpful 
>> in early deployment.
> 
> OK, well I get the --bti option then, but I still think that --bti-nowarn
> is a mistake.  Given that --bti will only generate warnings if there are
> object files without the BTI note, and warnings can be ignored, I do not
> see the need for --bti-nowarn.  Plus using --bti-nowarn could potentially
> cause problems if the developer forgets (or does not know) that it is
> enabled, and they end up thinking that they are creating BTI enabled
> binaries when in fact they are not.

Given this conversation, maybe renaming --bti to --force-bti would 
express the intention clearer ?


regards
Ramana
> 
> Cheers
>    Nick
> 
> 


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

* Re: [PATCH, BFD, LD, AArch64, 0/4] Add support for AArch64 BTI and PAC in the linker
  2019-03-08 11:14           ` Ramana Radhakrishnan
@ 2019-03-08 11:46             ` Peter Smith
  2019-03-08 12:32               ` Nick Clifton
  0 siblings, 1 reply; 22+ messages in thread
From: Peter Smith @ 2019-03-08 11:46 UTC (permalink / raw)
  To: Ramana Radhakrishnan
  Cc: nickc, Sudakshina Das, binutils, nd, Richard Earnshaw

On Fri, 8 Mar 2019 at 11:14, Ramana Radhakrishnan
<Ramana.Radhakrishnan@arm.com> wrote:
>
> On 08/03/2019 10:07, Nick Clifton wrote:
> > Hi Sudi,
> >
> >>> OK, so just to be clear, with --bti or --bti-nowarn the output will be
> >>> given the BTI tag *even if* some of the input files do not have the BTI note ?
> >
> >> Yes
> >
> >> can go back and check the objects that need recompiling or use
> >> --bti-nowarn when they are sure that even if there is any object with
> >> missing BTI note section it is still safe to turn on BTI (or they still
> >> want to turn on BTI). We think that these options would be most helpful
> >> in early deployment.
> >
> > OK, well I get the --bti option then, but I still think that --bti-nowarn
> > is a mistake.  Given that --bti will only generate warnings if there are
> > object files without the BTI note, and warnings can be ignored, I do not
> > see the need for --bti-nowarn.  Plus using --bti-nowarn could potentially
> > cause problems if the developer forgets (or does not know) that it is
> > enabled, and they end up thinking that they are creating BTI enabled
> > binaries when in fact they are not.
>
> Given this conversation, maybe renaming --bti to --force-bti would
> express the intention clearer ?
>
>
Indeed warnings can be ignored in most cases, particularly when there
aren't too many. In a large project the output could be large enough
to drown out other possibly more important warnings though. If there
were a way to generically suppress individual warnings then the case
for the separate command line option wouldn't be as good. Having said
that, I the nowarn form isn't as important as just --bti, or as Ramana
says --force-bti.

Peter

> regards
> Ramana
> >
> > Cheers
> >    Nick
> >
> >
>

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

* Re: [PATCH, BFD, LD, AArch64, 0/4] Add support for AArch64 BTI and PAC in the linker
  2019-03-08 11:46             ` Peter Smith
@ 2019-03-08 12:32               ` Nick Clifton
  2019-03-08 12:44                 ` Ramana Radhakrishnan
  0 siblings, 1 reply; 22+ messages in thread
From: Nick Clifton @ 2019-03-08 12:32 UTC (permalink / raw)
  To: Peter Smith, Ramana Radhakrishnan, Sudakshina Das
  Cc: binutils, nd, Richard Earnshaw

Hi Guys,

>> Given this conversation, maybe renaming --bti to --force-bti would
>> express the intention clearer ?

Yes - I rather like that idea.

> Indeed warnings can be ignored in most cases, particularly when there
> aren't too many. In a large project the output could be large enough
> to drown out other possibly more important warnings though.

Although I would suggest that warnings from the linker are a relatively
rare occurrence.  Unlike say a compiler ... :-)

In answer to Szabolcs's question:

> does -z ibt warn on x86_64?

No - it does not.  On the other hand, it does not force the enablement 
of ibt either.  In fact it appears to operate in the other way.  Linking
x86 binaries without specifying "-z ibt" or "-z ibtplt" on the command 
line will stop the linker from creating IBT enabled PLT entries, even if
all of the input object files would support them.


So - if we want to have the same behaviour in the AArch64 linker as we
currently have in the x86_64 linker, then how about this:

  * Without any specific command line options BTI and PAC are not
    enabled.  (Ie the dynamic tags are not added to the dynamic section).

  * With --bti specified, BTI is enabled in the output provided that
    the BTI note was found in all of the input files.  If one or more
    input files are missing the note, BTI is not enabled, no warnings
    are generated, *but* an entry is made in the linker map file indicating
    which object(s) caused BTI not to be enabled.  (Assuming that a
    linker map file is being generated).  This also matches the current
    behaviour of the x86_64 linker.

  * With --force-bti, BTI is enabled even if there are input files
    without the BTI note.  In this case, any file without the note
    triggers a warning message from the linker.

  * Similarly for PAC.  Ie --pac enables the PAC tag if all of the
    inputs support it, but no warnings are generated if some do not,
    and --force-pac always generates the PAC tag, but warns about
    object files that are missing the note.
    
What do people think ?

Cheers
  Nick

PS.  Sudi - the code for the patches themselves looks fine to me,
  so I have no concerns there.

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

* Re: [PATCH, BFD, LD, AArch64, 0/4] Add support for AArch64 BTI and PAC in the linker
  2019-03-08 12:32               ` Nick Clifton
@ 2019-03-08 12:44                 ` Ramana Radhakrishnan
  2019-03-08 13:36                   ` Sudakshina Das
  0 siblings, 1 reply; 22+ messages in thread
From: Ramana Radhakrishnan @ 2019-03-08 12:44 UTC (permalink / raw)
  To: nickc, Peter Smith, Sudakshina Das; +Cc: binutils, nd, Richard Earnshaw

On 08/03/2019 12:32, Nick Clifton wrote:
> Hi Guys,
> 
>>> Given this conversation, maybe renaming --bti to --force-bti would
>>> express the intention clearer ?
> 
> Yes - I rather like that idea.
> 
>> Indeed warnings can be ignored in most cases, particularly when there
>> aren't too many. In a large project the output could be large enough
>> to drown out other possibly more important warnings though.
> 
> Although I would suggest that warnings from the linker are a relatively
> rare occurrence.  Unlike say a compiler ... :-)
> 
> In answer to Szabolcs's question:
> 
>> does -z ibt warn on x86_64?
> 
> No - it does not.  On the other hand, it does not force the enablement
> of ibt either.  In fact it appears to operate in the other way.  Linking
> x86 binaries without specifying "-z ibt" or "-z ibtplt" on the command
> line will stop the linker from creating IBT enabled PLT entries, even if
> all of the input object files would support them.

Maybe that comes automatically from the compiler driver though a quick 
grep doesn't find me anything in the x86 backend.

> 
> 
> So - if we want to have the same behaviour in the AArch64 linker as we
> currently have in the x86_64 linker, then how about this:

Speaking for myself, that's a nice to have. I am all for commonality but 
if one choice is a better technical one and lesser work overall (see 
below) , it may make sense to revisit the x86 decision but that's not my 
call :)


> 
>    * Without any specific command line options BTI and PAC are not
>      enabled.  (Ie the dynamic tags are not added to the dynamic section).

But that in my book feels like more porting work for packagers - surely 
adding a linker flag to default passing on the flags from input object 
files to output ones is more work for all the packagers in the world.

I would prefer that if all input object files were marked with the BTI, 
the output had the flags on by default. If there was a missing object 
file, the linker should not mark the output file as BTI aware but should 
(up for grabs) warn that the link step missed things out. As you say 
linker warnings are rarer than compiler warnings and hopefully folks 
would pay attention.

It's only when things go wrong that folks have to intervene to 
investigate / diagnose issues. Otherwise we'd be scratching our heads or 
have to add an additional configure flag to get this default behaviour ?


> 
>    * With --bti specified, BTI is enabled in the output provided that
>      the BTI note was found in all of the input files.  If one or more
>      input files are missing the note, BTI is not enabled, no warnings
>      are generated, *but* an entry is made in the linker map file indicating
>      which object(s) caused BTI not to be enabled.  (Assuming that a
>      linker map file is being generated).  This also matches the current
>      behaviour of the x86_64 linker.

I feel this option is superfluous.

> 
>    * With --force-bti, BTI is enabled even if there are input files
>      without the BTI note.  In this case, any file without the note
>      triggers a warning message from the linker.

Thus in summary I would suggest renaming --bti to --force-bti and 
continue with existing behaviour.


> 
>    * Similarly for PAC.  Ie --pac enables the PAC tag if all of the
>      inputs support it, but no warnings are generated if some do not,
>      and --force-pac always generates the PAC tag, but warns about
>      object files that are missing the note.

As above.

Ramana

> 
> What do people think ?
> 
> Cheers
>    Nick
> 
> PS.  Sudi - the code for the patches themselves looks fine to me,
>    so I have no concerns there.


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

* Re: [PATCH, BFD, LD, AArch64, 0/4] Add support for AArch64 BTI and PAC in the linker
  2019-03-08 12:44                 ` Ramana Radhakrishnan
@ 2019-03-08 13:36                   ` Sudakshina Das
  2019-03-11 12:30                     ` Nick Clifton
  0 siblings, 1 reply; 22+ messages in thread
From: Sudakshina Das @ 2019-03-08 13:36 UTC (permalink / raw)
  To: Ramana Radhakrishnan, nickc, Peter Smith; +Cc: binutils, nd, Richard Earnshaw

Hi

On 08/03/2019 12:44, Ramana Radhakrishnan wrote:
> On 08/03/2019 12:32, Nick Clifton wrote:
>> Hi Guys,
>>
>>>> Given this conversation, maybe renaming --bti to --force-bti would
>>>> express the intention clearer ?
>>
>> Yes - I rather like that idea.
>>
>>> Indeed warnings can be ignored in most cases, particularly when there
>>> aren't too many. In a large project the output could be large enough
>>> to drown out other possibly more important warnings though.
>>
>> Although I would suggest that warnings from the linker are a relatively
>> rare occurrence.  Unlike say a compiler ... :-)
>>
>> In answer to Szabolcs's question:
>>
>>> does -z ibt warn on x86_64?
>>
>> No - it does not.  On the other hand, it does not force the enablement
>> of ibt either.  In fact it appears to operate in the other way.  Linking
>> x86 binaries without specifying "-z ibt" or "-z ibtplt" on the command
>> line will stop the linker from creating IBT enabled PLT entries, even if
>> all of the input object files would support them.
> 
> Maybe that comes automatically from the compiler driver though a quick
> grep doesn't find me anything in the x86 backend.
> 

My understanding on this is a bit different though! Take 
property-x86-ibt4.d test for example where a source without IBT note is 
linked with -z ibt and it gives out an IBT note (and no error/warning). 
Have I missed something?
>>
>>
>> So - if we want to have the same behaviour in the AArch64 linker as we
>> currently have in the x86_64 linker, then how about this:
> 
> Speaking for myself, that's a nice to have. I am all for commonality but
> if one choice is a better technical one and lesser work overall (see
> below) , it may make sense to revisit the x86 decision but that's not my
> call :)
> 
> 
>>
>>     * Without any specific command line options BTI and PAC are not
>>       enabled.  (Ie the dynamic tags are not added to the dynamic section).
> 
> But that in my book feels like more porting work for packagers - surely
> adding a linker flag to default passing on the flags from input object
> files to output ones is more work for all the packagers in the world.
> 
> I would prefer that if all input object files were marked with the BTI,
> the output had the flags on by default. If there was a missing object
> file, the linker should not mark the output file as BTI aware but should
> (up for grabs) warn that the link step missed things out. As you say
> linker warnings are rarer than compiler warnings and hopefully folks
> would pay attention.
> 

Personally I would also prefer if the default behavior for the linker is 
also to do BTI markings without any user options. But this does mean 
that we are going a different way from the existing x86_64 behavior.

> It's only when things go wrong that folks have to intervene to
> investigate / diagnose issues. Otherwise we'd be scratching our heads or
> have to add an additional configure flag to get this default behaviour ?
> 
> 
>>
>>     * With --bti specified, BTI is enabled in the output provided that
>>       the BTI note was found in all of the input files.  If one or more
>>       input files are missing the note, BTI is not enabled, no warnings
>>       are generated, *but* an entry is made in the linker map file indicating
>>       which object(s) caused BTI not to be enabled.  (Assuming that a
>>       linker map file is being generated).  This also matches the current
>>       behaviour of the x86_64 linker.
> 
> I feel this option is superfluous.
> 
>>
>>     * With --force-bti, BTI is enabled even if there are input files
>>       without the BTI note.  In this case, any file without the note
>>       triggers a warning message from the linker.
> 
> Thus in summary I would suggest renaming --bti to --force-bti and
> continue with existing behaviour.

I agree that --force-bti looks like a more appropriate name for the 
option. I am open to the idea of dropping --bti-nowarn 
(--force-bti-nowarn) assuming that if need be, users can ignore the 
warnings and go on doing what they want anyway.

@Nick, I hope that even though staying co-ordinated with x86_64 is 
desirable (to me as well in my personal opinion), our reasoning on the 
differences is convincing enough!

Sudi
> 
> 
>>
>>     * Similarly for PAC.  Ie --pac enables the PAC tag if all of the
>>       inputs support it, but no warnings are generated if some do not,
>>       and --force-pac always generates the PAC tag, but warns about
>>       object files that are missing the note.
> 
> As above.
> 
> Ramana
> 
>>
>> What do people think ?
>>
>> Cheers
>>     Nick
>>
>> PS.  Sudi - the code for the patches themselves looks fine to me,
>>     so I have no concerns there.
> 


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

* Re: [PATCH, BFD, LD, AArch64, 0/4] Add support for AArch64 BTI and PAC in the linker
  2019-03-08 13:36                   ` Sudakshina Das
@ 2019-03-11 12:30                     ` Nick Clifton
  2019-03-13 11:49                       ` Sudakshina Das
  0 siblings, 1 reply; 22+ messages in thread
From: Nick Clifton @ 2019-03-11 12:30 UTC (permalink / raw)
  To: Sudakshina Das, Ramana Radhakrishnan, Peter Smith
  Cc: binutils, nd, Richard Earnshaw

Hi Sudi,

>>>> does -z ibt warn on x86_64?
>>>
>>> No - it does not.  

>> Maybe that comes automatically from the compiler driver though a quick
>> grep doesn't find me anything in the x86 backend.

Hmm, true - I cannot find it either.


> My understanding on this is a bit different though! Take 
> property-x86-ibt4.d test for example where a source without IBT note is 
> linked with -z ibt and it gives out an IBT note (and no error/warning). 
> Have I missed something?

Nope, it must be me.  


>>>     * With --bti specified, BTI is enabled in the output provided that
>>>       the BTI note was found in all of the input files.  If one or more

>> I feel this option is superfluous.

Hmm, OK,

> I agree that --force-bti looks like a more appropriate name for the 
> option. I am open to the idea of dropping --bti-nowarn 
> (--force-bti-nowarn) assuming that if need be, users can ignore the 
> warnings and go on doing what they want anyway.
> 
> @Nick, I hope that even though staying co-ordinated with x86_64 is 
> desirable (to me as well in my personal opinion), our reasoning on the 
> differences is convincing enough!

It is.   :-)

OK, lets go with enabling BTI automatically, providing that all of
the inputs have the required notes.  The --force-bti option does
what it says, but generates warnings for any input that does not
have a note.

I still think that --force-bti-nowarn would be a dangerous option
to have, but if your toolchain guys really think that it is necessary
then I am not going to object to it any longer.

Patch series with the revised option name(s) approved.

Cheers
  Nick

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

* Re: [PATCH, BFD, LD, AArch64, 0/4] Add support for AArch64 BTI and PAC in the linker
  2019-03-11 12:30                     ` Nick Clifton
@ 2019-03-13 11:49                       ` Sudakshina Das
  0 siblings, 0 replies; 22+ messages in thread
From: Sudakshina Das @ 2019-03-13 11:49 UTC (permalink / raw)
  To: nickc, Ramana Radhakrishnan, Peter Smith; +Cc: binutils, nd, Richard Earnshaw

Hi Nick

On 11/03/2019 12:30, Nick Clifton wrote:
> Hi Sudi,
> 
>>>>> does -z ibt warn on x86_64?
>>>>
>>>> No - it does not.
> 
>>> Maybe that comes automatically from the compiler driver though a quick
>>> grep doesn't find me anything in the x86 backend.
> 
> Hmm, true - I cannot find it either.
> 
> 
>> My understanding on this is a bit different though! Take
>> property-x86-ibt4.d test for example where a source without IBT note is
>> linked with -z ibt and it gives out an IBT note (and no error/warning).
>> Have I missed something?
> 
> Nope, it must be me.
> 
> 
>>>>      * With --bti specified, BTI is enabled in the output provided that
>>>>        the BTI note was found in all of the input files.  If one or more
> 
>>> I feel this option is superfluous.
> 
> Hmm, OK,
> 
>> I agree that --force-bti looks like a more appropriate name for the
>> option. I am open to the idea of dropping --bti-nowarn
>> (--force-bti-nowarn) assuming that if need be, users can ignore the
>> warnings and go on doing what they want anyway.
>>
>> @Nick, I hope that even though staying co-ordinated with x86_64 is
>> desirable (to me as well in my personal opinion), our reasoning on the
>> differences is convincing enough!
> 
> It is.   :-)

Thanks :)
> 
> OK, lets go with enabling BTI automatically, providing that all of
> the inputs have the required notes.  The --force-bti option does
> what it says, but generates warnings for any input that does not
> have a note.
> 
> I still think that --force-bti-nowarn would be a dangerous option
> to have, but if your toolchain guys really think that it is necessary
> then I am not going to object to it any longer.
> 
> Patch series with the revised option name(s) approved.

Thank you. I have changed the option name to --force-bti and I have 
dropped the nowarn option. Patch 2 and 3 are thus merged into one and 
committed the series of 3 patches!

Thanks
Sudi

> 
> Cheers
>    Nick
> 


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

* Re: [PATCH, BFD, LD, AArch64, 4/4] Add --pac-plt to enable PLTs protected with PAC.
  2019-03-06 10:39       ` [PATCH, BFD, LD, AArch64, 4/4] Add --pac-plt to enable PLTs protected with PAC Sudakshina Das
@ 2019-04-11 14:47         ` Szabolcs Nagy
  0 siblings, 0 replies; 22+ messages in thread
From: Szabolcs Nagy @ 2019-04-11 14:47 UTC (permalink / raw)
  To: Sudakshina Das, binutils; +Cc: nd, nickc, Ramana Radhakrishnan

On 06/03/2019 10:39, Sudakshina Das wrote:
> +static const bfd_byte elfNN_aarch64_small_plt0_pac_entry[PLT_PAC_ENTRY_SIZE] =
> +{
> +  0xf0, 0x7b, 0xbf, 0xa9,	/* stp x16, x30, [sp, #-16]!  */
> +  0x10, 0x00, 0x00, 0x90,	/* adrp x16, (GOT+16)  */
> +#if ARCH_SIZE == 64
> +  0x11, 0x0A, 0x40, 0xf9,	/* ldr x17, [x16, #PLT_GOT+0x10]  */
> +  0x10, 0x42, 0x00, 0x91,	/* add x16, x16,#PLT_GOT+0x10   */
> +#else
> +  0x11, 0x0A, 0x40, 0xb9,	/* ldr w17, [x16, #PLT_GOT+0x8]  */
> +  0x10, 0x22, 0x00, 0x11,	/* add w16, w16,#PLT_GOT+0x8   */
> +#endif
> +  0x9f, 0x21, 0x03, 0xd5,	/* autia1716 */
> +  0x20, 0x02, 0x1f, 0xd6,	/* br x17  */
> +  0x1f, 0x20, 0x03, 0xd5,	/* nop */
> +  0x1f, 0x20, 0x03, 0xd5,	/* nop */
> +  0x1f, 0x20, 0x03, 0xd5,	/* nop */
> +};
> +
> +static const bfd_byte
> +elfNN_aarch64_small_plt0_bti_pac_entry[PLT_BTI_PAC_ENTRY_SIZE] =
> +{
> +  0x5f, 0x24, 0x03, 0xd5,	/* bti c.  */
> +  0xf0, 0x7b, 0xbf, 0xa9,	/* stp x16, x30, [sp, #-16]!  */
> +  0x10, 0x00, 0x00, 0x90,	/* adrp x16, (GOT+16)  */
> +#if ARCH_SIZE == 64
> +  0x11, 0x0A, 0x40, 0xf9,	/* ldr x17, [x16, #PLT_GOT+0x10]  */
> +  0x10, 0x42, 0x00, 0x91,	/* add x16, x16,#PLT_GOT+0x10   */
> +#else
> +  0x11, 0x0A, 0x40, 0xb9,	/* ldr w17, [x16, #PLT_GOT+0x8]  */
> +  0x10, 0x22, 0x00, 0x11,	/* add w16, w16,#PLT_GOT+0x8   */
> +#endif
> +  0x9f, 0x21, 0x03, 0xd5,	/* autia1716 */
> +  0x20, 0x02, 0x1f, 0xd6,	/* br x17  */
> +  0x1f, 0x20, 0x03, 0xd5,	/* nop */
> +  0x1f, 0x20, 0x03, 0xd5,	/* nop */
> +  0x1f, 0x20, 0x03, 0xd5,	/* nop */
> +};

sorry i hadn't noticed this before,
PLT0 does not need a PAC variant because the
PLTGOT[2] entry that's loaded here is readonly
protected under relro (i think the linker
script magic for relro guarantees this).

in principle using autia here works too
(just additional unnecessary autia in the lazy
resolution code path), however this is ABI
between a dynamic linker and static linker:
with such PLT0 the PLTGOT[2] has to be filled
in with a signed pointer.

it seems our ELF ABI does not describe this
(PLT sequence should be in the SYS V ABI),
i think if we agree that relro always protects
PLTGOT[2] then we can still change this.
(to reduce the number of supported PLT0 entries)

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

end of thread, other threads:[~2019-04-11 14:47 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-03-06 10:26 [PATCH, BFD, LD, AArch64, 0/4] Add support for AArch64 BTI and PAC in the linker Sudakshina Das
2019-03-06 10:31 ` [PATCH, BFD, LD, AArch64, 1/4] Add support for GNU PROPERTIES in AArch64 for BTI and PAC Sudakshina Das
2019-03-06 10:34   ` [PATCH, BFD, LD, AArch64, 2/4] Add --bti-nowarn to enable BTI without warning and to select BTI enabled PLTs Sudakshina Das
2019-03-06 10:36     ` [PATCH, BFD, LD, AArch64, 3/4] Add --bti to enable BTI and select BTI enabled PLTs but also warn for missing NOTE sections Sudakshina Das
2019-03-06 10:39       ` [PATCH, BFD, LD, AArch64, 4/4] Add --pac-plt to enable PLTs protected with PAC Sudakshina Das
2019-04-11 14:47         ` Szabolcs Nagy
2019-03-07 12:37 ` [PATCH, BFD, LD, AArch64, 0/4] Add support for AArch64 BTI and PAC in the linker Nick Clifton
2019-03-07 14:28   ` Sudakshina Das
2019-03-07 15:26     ` Peter Smith
2019-03-07 15:35       ` Nick Clifton
2019-03-07 15:49         ` Szabolcs Nagy
2019-03-07 15:33     ` Nick Clifton
2019-03-07 17:53       ` Sudakshina Das
2019-03-08 10:07         ` Nick Clifton
2019-03-08 11:08           ` Szabolcs Nagy
2019-03-08 11:14           ` Ramana Radhakrishnan
2019-03-08 11:46             ` Peter Smith
2019-03-08 12:32               ` Nick Clifton
2019-03-08 12:44                 ` Ramana Radhakrishnan
2019-03-08 13:36                   ` Sudakshina Das
2019-03-11 12:30                     ` Nick Clifton
2019-03-13 11:49                       ` Sudakshina Das

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