public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [BFD, LD] aarch64: Add support for GCS in AArch64 linker.
@ 2024-01-04 17:23 Srinath Parvathaneni
  2024-01-05 10:57 ` Nick Clifton
  0 siblings, 1 reply; 3+ messages in thread
From: Srinath Parvathaneni @ 2024-01-04 17:23 UTC (permalink / raw)
  To: binutils; +Cc: Richard Earnshaw, nickc


[-- Attachment #1.1: Type: text/plain, Size: 1656 bytes --]

Hi,

This patch adds support for GCS in AArch64 linker.

This patch implements the following:
1) Defines GNU_PROPERTY_AARCH64_FEATURE_1_GCS bit for GCS in
GNU_PROPERTY_AARCH64_FEATURE_1_AND macro.

#define GNU_PROPERTY_AARCH64_FEATURE_1_GCS     (1U << 2)

2) Adds readelf support to read and print the GNU properties
in AArch64.

Displaying notes found in: .note.gnu.property
[      ]+Owner[        ]+Data size[    ]+Description
   GNU                  0x00000010      NT_GNU_PROPERTY_TYPE_0
       Properties: AArch64 feature: GCS

3) Adds support for -z experimental-gcs linker option and document
all the values allowed with option (-z experimental-gcs[=always|never|implicit]).
-z experimental-gcs is equivalent to -z experimental-gcs=always and
when option is not passed in the command line, it defaults to implicit.

4) Adds support for -z experimental-gcs-report linker option and document
all the values allowed with this option (-z experimental-gcs-report[=none|warning|error]).
-z experimental-gcs-report is equivalent to -z experimental-gcs-report=none
and when option is not passed in the command line, it defaults to none.

The ABI changes adding GNU_PROPERTY_AARCH64_FEATURE_1_GCS to the
GNU property GNU_PROPERTY_AARCH64_FEATURE_1_AND is merged into main and
can be found below.
https://github.com/ARM-software/abi-aa/blob/main/sysvabi64/sysvabi64.rst

Regression testing for aarch64-none-linux-gnu target and found no regressions.

This patch will not be committed to development branch until the Kernel GCS
ABI changes are approved and committed.

Ok to commit this patch to Arm vendor branch based on binutils-master ?

Regards,
Srinath.

[-- Attachment #2: gcs_linker --]
[-- Type: text/plain, Size: 35552 bytes --]

diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c
index 4faf642b422ffdff5c7879bff6bd08991b38eab8..8ff74295c5cc51221bf4279bd5bc135362e7d60e 100644
--- a/bfd/elfnn-aarch64.c
+++ b/bfd/elfnn-aarch64.c
@@ -2546,6 +2546,12 @@ struct elf_aarch64_obj_tdata
      GNU_PROPERTY_AARCH64_FEATURE_1_BTI.  */
   int no_bti_warn;
 
+  /* Mark ouput with GCS based on -z experimental-gcs.  */
+  aarch64_gcs_type gcs_type;
+  /* Report linker warning/error for -z experimental-gcs-report based on
+     -z experimental-gcs.  */
+  aarch64_gcs_report gcs_report;
+
   /* PLT type based on security.  */
   aarch64_plt_type plt_type;
 };
@@ -5011,7 +5017,7 @@ bfd_elfNN_aarch64_set_options (struct bfd *output_bfd,
 			       int fix_erratum_835769,
 			       erratum_84319_opts fix_erratum_843419,
 			       int no_apply_dynamic_relocs,
-			       aarch64_bti_pac_info bp_info)
+			       aarch64_gnu_prop_info bp_info)
 {
   struct elf_aarch64_link_hash_table *globals;
 
@@ -5039,6 +5045,24 @@ bfd_elfNN_aarch64_set_options (struct bfd *output_bfd,
     default:
       break;
     }
+
+  switch (bp_info.gcs_type)
+    {
+    case GCS_ALWAYS:
+      elf_aarch64_tdata (output_bfd)->gnu_and_prop
+	|= GNU_PROPERTY_AARCH64_FEATURE_1_GCS;
+      break;
+    case GCS_NEVER:
+      elf_aarch64_tdata (output_bfd)->gnu_and_prop
+	&= ~GNU_PROPERTY_AARCH64_FEATURE_1_GCS;
+      break;
+
+    default:
+      break;
+    }
+
+  elf_aarch64_tdata (output_bfd)->gcs_type = bp_info.gcs_type;
+  elf_aarch64_tdata (output_bfd)->gcs_report = bp_info.gcs_report;
   elf_aarch64_tdata (output_bfd)->plt_type = bp_info.plt_type;
   setup_plt_values (link_info, bp_info.plt_type);
 }
@@ -10196,7 +10220,12 @@ 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);
+  aarch64_gcs_report gcs_report
+    = elf_aarch64_tdata (info->output_bfd)->gcs_report;
+  aarch64_gcs_report gcs_type
+    = elf_aarch64_tdata (info->output_bfd)->gcs_type;
+  bfd *pbfd = _bfd_aarch64_elf_link_setup_gnu_properties (info, &prop,
+							  gcs_report, gcs_type);
   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;
@@ -10215,30 +10244,54 @@ elfNN_aarch64_merge_gnu_properties (struct bfd_link_info *info,
 {
   uint32_t prop
     = elf_aarch64_tdata (info->output_bfd)->gnu_and_prop;
+  aarch64_gcs_report gcs_report
+    = elf_aarch64_tdata (info->output_bfd)->gcs_report;
+  aarch64_gcs_type gcs_type
+    = elf_aarch64_tdata (info->output_bfd)->gcs_type;
 
-  /* If output has been marked with BTI using command line argument, give out
-     warning if necessary.  */
   /* Properties are merged per type, hence only check for warnings when merging
      GNU_PROPERTY_AARCH64_FEATURE_1_AND.  */
-  if (((aprop && aprop->pr_type == GNU_PROPERTY_AARCH64_FEATURE_1_AND)
+  if ((aprop && aprop->pr_type == GNU_PROPERTY_AARCH64_FEATURE_1_AND)
 	|| (bprop && bprop->pr_type == GNU_PROPERTY_AARCH64_FEATURE_1_AND))
-      && (prop & GNU_PROPERTY_AARCH64_FEATURE_1_BTI)
-      && (!elf_aarch64_tdata (info->output_bfd)->no_bti_warn))
     {
-      if ((aprop && !(aprop->u.number & GNU_PROPERTY_AARCH64_FEATURE_1_BTI))
-	   || !aprop)
+      /* 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_bti_warn))
 	{
-	  _bfd_error_handler (_("%pB: warning: BTI turned on by -z force-bti when "
-				"all inputs do not have BTI in NOTE section."),
-			      abfd);
+	  if ((aprop && !(aprop->u.number & GNU_PROPERTY_AARCH64_FEATURE_1_BTI))
+	      || !aprop)
+	    {
+	      _bfd_error_handler (_("%pB: warning: BTI turned on by -z "
+				  "force-bti when all inputs do not have BTI "
+				  "in NOTE section."), abfd);
+	    }
+	  if ((bprop && !(bprop->u.number & GNU_PROPERTY_AARCH64_FEATURE_1_BTI))
+	      || !bprop)
+	    {
+	      _bfd_error_handler (_("%pB: warning: BTI turned on by -z "
+				  "force-bti when all inputs do not have BTI "
+				  "in NOTE section."), bbfd);
+	    }
 	}
-      if ((bprop && !(bprop->u.number & GNU_PROPERTY_AARCH64_FEATURE_1_BTI))
-	   || !bprop)
+
+      /* If output has been marked with GCS using -z experimental-gcs and input
+	 is missing GCS marking throw warning/error on
+	 -z experimental-gcs-report=warning/error.  */
+      if ((prop & GNU_PROPERTY_AARCH64_FEATURE_1_GCS) && gcs_report != GCS_NONE)
 	{
-	  _bfd_error_handler (_("%pB: warning: BTI turned on by -z force-bti when "
-				"all inputs do not have BTI in NOTE section."),
-			      bbfd);
+	  if ((aprop && !(aprop->u.number & GNU_PROPERTY_AARCH64_FEATURE_1_GCS))
+	      || !aprop)
+	    _bfd_aarch64_elf_check_gcs_report (gcs_report, abfd);
+	  if ((bprop && !(bprop->u.number & GNU_PROPERTY_AARCH64_FEATURE_1_GCS))
+	      || !bprop)
+	    _bfd_aarch64_elf_check_gcs_report (gcs_report, bbfd);
 	}
+
+      if (gcs_type == GCS_NEVER && aprop != NULL)
+	aprop->u.number &= ~GNU_PROPERTY_AARCH64_FEATURE_1_GCS;
+      if (gcs_type == GCS_NEVER && bprop != NULL)
+	bprop->u.number &= ~GNU_PROPERTY_AARCH64_FEATURE_1_GCS;
     }
 
   return  _bfd_aarch64_elf_merge_gnu_properties (info, abfd, aprop,
diff --git a/bfd/elfxx-aarch64.h b/bfd/elfxx-aarch64.h
index 3afc47c0dbafe3667ed0c0a00c87285b7133fd0e..015b3a0d3ac5b13ac092c351df280c46ce8e62ab 100644
--- a/bfd/elfxx-aarch64.h
+++ b/bfd/elfxx-aarch64.h
@@ -46,6 +46,27 @@ typedef enum
   BTI_WARN	= 1,  /* BTI is enabled with -z force-bti.  */
 } aarch64_enable_bti_type;
 
+/* To indicate whether GNU_PROPERTY_AARCH64_FEATURE_1_GCS bit is
+   enabled/disabled on the output when -z experimental-gcs linker
+   command line option is passed.  */
+typedef enum
+{
+  GCS_NEVER	= 0,  /* gcs is disabled on output.  */
+  GCS_IMPLICIT  = 1,  /* gcs is deduced from input object.  */
+  GCS_ALWAYS	= 2,  /* gsc is enabled on output.  */
+} aarch64_gcs_type;
+
+/* To indicate whether to generate linker warning/errors for
+   -z experimental-gcs-report when -z experimental-gcs=always is passed.  */
+typedef enum
+{
+  GCS_NONE	= 0,  /* Does not emit any warning/error messages.  */
+  GCS_WARN	= 1,  /* Emit warning when the input objects are missing gcs
+			 markings and output have gcs marking.  */
+  GCS_ERROR	= 2,  /* Emit error when the input objects are missing gcs
+			 markings and output have gcs marking.  */
+} aarch64_gcs_report;
+
 /* 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
@@ -54,7 +75,9 @@ typedef struct
 {
   aarch64_plt_type plt_type;
   aarch64_enable_bti_type bti_type;
-} aarch64_bti_pac_info;
+  aarch64_gcs_type gcs_type;
+  aarch64_gcs_report gcs_report;
+} aarch64_gnu_prop_info;
 
 /* An enum to define what kind of erratum fixes we should apply.  This gives the
    user a bit more control over the sequences we generate.  */
@@ -67,11 +90,11 @@ typedef enum
 
 extern void bfd_elf64_aarch64_set_options
   (bfd *, struct bfd_link_info *, int, int, int, int, erratum_84319_opts, int,
-   aarch64_bti_pac_info);
+   aarch64_gnu_prop_info);
 
 extern void bfd_elf32_aarch64_set_options
   (bfd *, struct bfd_link_info *, int, int, int, int, erratum_84319_opts, int,
-   aarch64_bti_pac_info);
+   aarch64_gnu_prop_info);
 
 /* AArch64 stub generation support for ELF64.  Called from the linker.  */
 extern int elf64_aarch64_setup_section_lists
@@ -135,8 +158,9 @@ _bfd_aarch64_elf_write_core_note (bfd *, char *, int *, int, ...);
 #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 *);
+_bfd_aarch64_elf_link_setup_gnu_properties (struct bfd_link_info *, uint32_t *,
+					    aarch64_gcs_report,
+					    aarch64_gcs_type);
 
 extern enum elf_property_kind
 _bfd_aarch64_elf_parse_gnu_properties (bfd *, unsigned int,
@@ -146,6 +170,8 @@ extern bool
 _bfd_aarch64_elf_merge_gnu_properties (struct bfd_link_info *, bfd *,
 				       elf_property *, elf_property *,
 				       uint32_t);
+extern void
+_bfd_aarch64_elf_check_gcs_report (aarch64_gcs_report, bfd *);
 
 extern void
 _bfd_aarch64_elf_link_fixup_gnu_properties (struct bfd_link_info *,
diff --git a/bfd/elfxx-aarch64.c b/bfd/elfxx-aarch64.c
index cd0c0e6eaa97ac044fd2fec4d16350d9ceed1cb1..f5bcabdb0a7a62144315b2a2cb0d62f045ae95f8 100644
--- a/bfd/elfxx-aarch64.c
+++ b/bfd/elfxx-aarch64.c
@@ -702,7 +702,9 @@ _bfd_aarch64_elf_write_core_note (bfd *abfd, char *buf, int *bufsiz, int note_ty
    GPROP accordingly.  */
 bfd *
 _bfd_aarch64_elf_link_setup_gnu_properties (struct bfd_link_info *info,
-					    uint32_t *gprop)
+					    uint32_t *gprop,
+					    aarch64_gcs_report gcs_report,
+					    aarch64_gcs_type gcs_type)
 {
   asection *sec;
   bfd *pbfd;
@@ -738,6 +740,11 @@ _bfd_aarch64_elf_link_setup_gnu_properties (struct bfd_link_info *info,
 	    _bfd_error_handler (_("%pB: warning: BTI turned on by -z force-bti "
 				  "when all inputs do not have BTI in NOTE "
 				  "section."), ebfd);
+
+      if ((gnu_prop & GNU_PROPERTY_AARCH64_FEATURE_1_GCS)
+	  && !(prop->u.number & GNU_PROPERTY_AARCH64_FEATURE_1_GCS))
+	_bfd_aarch64_elf_check_gcs_report (gcs_report, ebfd);
+
       prop->u.number |= gnu_prop;
       prop->pr_kind = property_number;
 
@@ -765,6 +772,14 @@ _bfd_aarch64_elf_link_setup_gnu_properties (struct bfd_link_info *info,
 	  elf_section_type (sec) = SHT_NOTE;
 	}
     }
+  else if (ebfd != NULL && gcs_type == GCS_NEVER)
+    {
+      prop = _bfd_elf_get_property (ebfd, GNU_PROPERTY_AARCH64_FEATURE_1_AND,
+				    4);
+      prop->u.number &= ~GNU_PROPERTY_AARCH64_FEATURE_1_GCS;
+      if (prop->u.number == 0)
+	prop->pr_kind = property_remove;
+    }
 
   pbfd = _bfd_elf_link_setup_gnu_properties (info);
 
@@ -785,7 +800,8 @@ _bfd_aarch64_elf_link_setup_gnu_properties (struct bfd_link_info *info,
 	    {
 	      gnu_prop = (p->property.u.number
 			  & (GNU_PROPERTY_AARCH64_FEATURE_1_PAC
-			      | GNU_PROPERTY_AARCH64_FEATURE_1_BTI));
+			      | GNU_PROPERTY_AARCH64_FEATURE_1_BTI
+			      | GNU_PROPERTY_AARCH64_FEATURE_1_GCS));
 	      break;
 	    }
 	  else if (GNU_PROPERTY_AARCH64_FEATURE_1_AND < p->property.pr_type)
@@ -922,3 +938,20 @@ _bfd_aarch64_elf_link_fixup_gnu_properties
 	}
     }
 }
+
+/* Check AArch64 GCS report.  */
+void
+_bfd_aarch64_elf_check_gcs_report (aarch64_gcs_report gcs_report, bfd *ebfd)
+{
+  if (gcs_report == GCS_WARN)
+    _bfd_error_handler (_("%pB: warning: GCS turned on by -z experimental-gcs "
+			"on the output when all inputs do not have GCS in NOTE "
+			"section."), ebfd);
+  else if (gcs_report == GCS_ERROR)
+    {
+      _bfd_error_handler (_("%pB: error: GCS turned on by -z experimental-gcs "
+			  "on the output when all inputs do not have GCS in "
+			  "NOTE section."), ebfd);
+      _exit (EXIT_FAILURE);
+    }
+}
diff --git a/binutils/readelf.c b/binutils/readelf.c
index 775106fb99c5d8926c5e10a6e4e1f8662d60e8d4..48eee59658969f746a700b662f24ab0f8bb86621 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -20634,6 +20634,10 @@ decode_aarch64_feature_1_and (unsigned int bitmask)
 	  printf ("PAC");
 	  break;
 
+	case GNU_PROPERTY_AARCH64_FEATURE_1_GCS:
+	  printf ("GCS");
+	  break;
+
 	default:
 	  printf (_("<unknown: %x>"), bit);
 	  break;
diff --git a/include/elf/common.h b/include/elf/common.h
index 244b13361e5e135058e582df06d339fb3b69ab82..9013c11a4202760b983db09ef98618993eef4bf8 100644
--- a/include/elf/common.h
+++ b/include/elf/common.h
@@ -998,6 +998,7 @@
 
 #define GNU_PROPERTY_AARCH64_FEATURE_1_BTI	(1U << 0)
 #define GNU_PROPERTY_AARCH64_FEATURE_1_PAC	(1U << 1)
+#define GNU_PROPERTY_AARCH64_FEATURE_1_GCS	(1U << 2)
 
 /* Values used in GNU .note.ABI-tag notes (NT_GNU_ABI_TAG).  */
 #define GNU_ABI_TAG_LINUX	0
diff --git a/ld/emultempl/aarch64elf.em b/ld/emultempl/aarch64elf.em
index d47bdbf9937d4c1a31d85ebd52b7483ef88bf3db..47c2656df025d8a05301a632dc9df81f67eb2606 100644
--- a/ld/emultempl/aarch64elf.em
+++ b/ld/emultempl/aarch64elf.em
@@ -36,6 +36,8 @@ static erratum_84319_opts fix_erratum_843419 = ERRAT_NONE;
 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 aarch64_gcs_type gcs_type = GCS_IMPLICIT;
+static aarch64_gcs_report gcs_report = GCS_NONE;
 
 static void
 gld${EMULATION_NAME}_before_parse (void)
@@ -321,9 +323,11 @@ aarch64_elf_create_output_section_statements (void)
       return;
     }
 
-  aarch64_bti_pac_info bp_info;
+  aarch64_gnu_prop_info bp_info;
   bp_info.plt_type = plt_type;
   bp_info.bti_type = bti_type;
+  bp_info.gcs_type = gcs_type;
+  bp_info.gcs_report = gcs_report;
 
   bfd_elf${ELFSIZE}_aarch64_set_options (link_info.output_bfd, &link_info,
 				 no_enum_size_warning,
@@ -408,6 +412,19 @@ PARSE_AND_LIST_OPTIONS='
   fprintf (file, _("  --no-apply-dynamic-relocs    Do not apply link-time values for dynamic relocations\n"));
   fprintf (file, _("  -z force-bti                  Turn on Branch Target Identification mechanism and generate PLTs with BTI. Generate warnings for missing BTI on inputs\n"));
   fprintf (file, _("  -z pac-plt                    Protect PLTs with Pointer Authentication.\n"));
+  fprintf (file, _("\
+  -z experimental-gcs[=always|never|implicit]		Turn on Guarded Control Stack(gcs) mechanism on the output.\n\
+							implicit(default): deduce gcs from input objects.\n\
+							always: always marks the output with gcs.\n\
+							never: never marks the output with gcs.\n"));
+  fprintf (file, _("\
+  -z experimental-gcs-report[=none|warning|error]	Emit warning/error on mismatch of gcs marking between input objects and ouput.\n\
+							none (default): Does not emit any warning/error messages.\n\
+							warning: Emit warning when the input objects are missing gcs markings\n\
+								 and output have gcs marking.\n\
+							error: Emit error when the input objects are missing gcs markings\n\
+							       and output have gcs marking.\n"));
+
 '
 
 PARSE_AND_LIST_ARGS_CASE_Z_AARCH64='
@@ -418,6 +435,28 @@ PARSE_AND_LIST_ARGS_CASE_Z_AARCH64='
 	}
       else if (strcmp (optarg, "pac-plt") == 0)
 	plt_type |= PLT_PAC;
+     else if (strncmp (optarg, "experimental-gcs-report", 23) == 0)
+	{
+	  if (strlen (optarg) == 23 || strcmp (optarg + 23, "=none") == 0)
+	    gcs_report = GCS_NONE;
+	  else if (strcmp (optarg + 23, "=warning") == 0)
+	    gcs_report = GCS_WARN;
+	  else if (strcmp (optarg + 23, "=error") == 0)
+	    gcs_report = GCS_ERROR;
+	  else
+	    einfo (_("%P: error: unrecognized: `%s'\''\n"), optarg);
+	}
+     else if (strncmp (optarg, "experimental-gcs", 16) == 0)
+	{
+	  if (strlen (optarg) == 16 || strcmp (optarg + 16, "=always") == 0)
+	    gcs_type = GCS_ALWAYS;
+	  else if (strcmp (optarg + 16, "=never") == 0)
+	    gcs_type = GCS_NEVER;
+	  else if (strcmp (optarg + 16, "=implicit") == 0)
+	    gcs_type = GCS_IMPLICIT;
+	  else
+	    einfo (_("%P: error: unrecognized: `%s'\''\n"), optarg);
+	}
 '
 PARSE_AND_LIST_ARGS_CASE_Z="$PARSE_AND_LIST_ARGS_CASE_Z $PARSE_AND_LIST_ARGS_CASE_Z_AARCH64"
 
diff --git a/ld/testsuite/ld-aarch64/aarch64-elf.exp b/ld/testsuite/ld-aarch64/aarch64-elf.exp
index 37e3b82af5739ac79ef9f173088343224b988052..490ae640feca617440374027d1c3e339537040f4 100644
--- a/ld/testsuite/ld-aarch64/aarch64-elf.exp
+++ b/ld/testsuite/ld-aarch64/aarch64-elf.exp
@@ -471,3 +471,26 @@ run_dump_test_lp64 "bti-far-3"
 if { ![skip_sframe_tests] } {
   run_dump_test "sframe-simple-1"
 }
+
+run_dump_test "property-gcs1"
+run_dump_test "property-gcs2"
+run_dump_test "property-gcs3"
+run_dump_test "property-gcs4"
+run_dump_test "property-gcs5"
+run_dump_test "property-gcs6"
+run_dump_test "property-gcs7"
+run_dump_test "property-gcs8"
+run_dump_test "property-gcs9"
+run_dump_test "property-gcs10"
+run_dump_test "property-gcs11"
+run_dump_test "property-gcs12"
+run_dump_test "property-gcs13"
+run_dump_test "property-gcs14"
+run_dump_test "property-gcs15"
+run_dump_test "property-gcs16"
+run_dump_test "property-gcs17"
+run_dump_test "property-gcs18"
+run_dump_test "property-gcs19"
+run_dump_test "property-gcs20"
+run_dump_test "property-gcs21"
+run_dump_test "property-gcs22"
diff --git a/ld/testsuite/ld-aarch64/property-bti-pac1.d b/ld/testsuite/ld-aarch64/property-bti-pac1.d
index 59fa695165aa2fff603c2d4156c284bf08e2c072..c28a0cbf850f4dee288901c84047ba3c55611ea7 100644
--- a/ld/testsuite/ld-aarch64/property-bti-pac1.d
+++ b/ld/testsuite/ld-aarch64/property-bti-pac1.d
@@ -8,4 +8,4 @@
 Displaying notes found in: .note.gnu.property
 [ 	]+Owner[ 	]+Data size[ 	]+Description
   GNU                  0x00000010	NT_GNU_PROPERTY_TYPE_0
-      Properties: AArch64 feature: BTI, PAC
+      Properties: AArch64 feature: BTI, PAC, GCS
diff --git a/ld/testsuite/ld-aarch64/property-bti-pac1.s b/ld/testsuite/ld-aarch64/property-bti-pac1.s
index 414c9277f1dabc5fdc08b8b71716c44ea8bc8343..42156917d587491fafe6de575669166c7c9459be 100644
--- a/ld/testsuite/ld-aarch64/property-bti-pac1.s
+++ b/ld/testsuite/ld-aarch64/property-bti-pac1.s
@@ -12,6 +12,20 @@ _start:
 	.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 0x4		/* GCS.  */
+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.  */
diff --git a/ld/testsuite/ld-aarch64/property-gcs.s b/ld/testsuite/ld-aarch64/property-gcs.s
new file mode 100644
index 0000000000000000000000000000000000000000..bc7e66e89338a94ef2bfe68bb20671e896404e93
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/property-gcs.s
@@ -0,0 +1,25 @@
+	.text
+	.globl _start
+	.type _start,@function
+_start:
+	mov x1, #2
+.ifndef __mult__
+	bl foo
+.endif
+.ifdef __property_gcs__
+	.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 0x4		/* GCS.  */
+4:
+	.p2align 3
+5:
+.endif
diff --git a/ld/testsuite/ld-aarch64/property-gcs1.d b/ld/testsuite/ld-aarch64/property-gcs1.d
new file mode 100644
index 0000000000000000000000000000000000000000..c724ac56ca3f612ad2b109d465918990fcfee8f8
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/property-gcs1.d
@@ -0,0 +1,6 @@
+#name: GNU Property (input without gcs)
+#source: property-gcs.s
+#alltargets: [check_shared_lib_support] *linux*
+#as: -march=armv9.4-a+gcs -defsym __mult__=0
+#ld: -shared
+#readelf: -n
diff --git a/ld/testsuite/ld-aarch64/property-gcs10.d b/ld/testsuite/ld-aarch64/property-gcs10.d
new file mode 100644
index 0000000000000000000000000000000000000000..4b6deedc0c205aaaf30414c5586ecfe1ba4dcf8b
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/property-gcs10.d
@@ -0,0 +1,6 @@
+#name: GNU Property (input without gcs ouput forced with experimental-gcs=always experimental-gcs-report=error)
+#source: property-gcs.s
+#alltargets: [check_shared_lib_support] *linux*
+#as: -march=armv9.4-a+gcs -defsym __mult__=0
+#ld: -z experimental-gcs=always -z experimental-gcs-report=error
+#error: .*property-gcs.*: error: GCS turned on by -z experimental-gcs on the output when all inputs do not have GCS in NOTE section.
diff --git a/ld/testsuite/ld-aarch64/property-gcs11.d b/ld/testsuite/ld-aarch64/property-gcs11.d
new file mode 100644
index 0000000000000000000000000000000000000000..8abacf28eb1bbaa179ddbd9ff08753c844eca7c1
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/property-gcs11.d
@@ -0,0 +1,11 @@
+#name: GNU Property (input with gcs output forced with experimental-gcs)
+#source: property-gcs.s
+#alltargets: [check_shared_lib_support] *linux*
+#as: -march=armv9.4-a+gcs -defsym __mult__=0 -defsym __property_gcs__=1
+#ld: -z experimental-gcs
+#readelf: -n
+
+Displaying notes found in: .note.gnu.property
+[ 	]+Owner[ 	]+Data size[ 	]+Description
+  GNU                  0x00000010	NT_GNU_PROPERTY_TYPE_0
+      Properties: AArch64 feature: GCS
diff --git a/ld/testsuite/ld-aarch64/property-gcs12.d b/ld/testsuite/ld-aarch64/property-gcs12.d
new file mode 100644
index 0000000000000000000000000000000000000000..0fe246dfa3a75972be0d3cce32d30a8d5305855e
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/property-gcs12.d
@@ -0,0 +1,11 @@
+#name: GNU Property (input with gcs ouput forced with experimental-gcs=always)
+#source: property-gcs.s
+#alltargets: [check_shared_lib_support] *linux*
+#as: -march=armv9.4-a+gcs -defsym __mult__=0 -defsym __property_gcs__=1
+#ld: -z experimental-gcs=always
+#readelf: -n
+
+Displaying notes found in: .note.gnu.property
+[ 	]+Owner[ 	]+Data size[ 	]+Description
+  GNU                  0x00000010	NT_GNU_PROPERTY_TYPE_0
+      Properties: AArch64 feature: GCS
diff --git a/ld/testsuite/ld-aarch64/property-gcs13.d b/ld/testsuite/ld-aarch64/property-gcs13.d
new file mode 100644
index 0000000000000000000000000000000000000000..c6077aeaa5ace7a7f467b8bef45f7fa2de733fee
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/property-gcs13.d
@@ -0,0 +1,11 @@
+#name: GNU Property (input with gcs ouput forced with experimental-gcs experimental-gcs-report=none)
+#source: property-gcs.s
+#alltargets: [check_shared_lib_support] *linux*
+#as: -march=armv9.4-a+gcs -defsym __mult__=0 -defsym __property_gcs__=1
+#ld: -z experimental-gcs -z experimental-gcs-report=none
+#readelf: -n
+
+Displaying notes found in: .note.gnu.property
+[ 	]+Owner[ 	]+Data size[ 	]+Description
+  GNU                  0x00000010	NT_GNU_PROPERTY_TYPE_0
+      Properties: AArch64 feature: GCS
diff --git a/ld/testsuite/ld-aarch64/property-gcs14.d b/ld/testsuite/ld-aarch64/property-gcs14.d
new file mode 100644
index 0000000000000000000000000000000000000000..0f7490ef4a5d638aaad4d301f63cb20cfd86b1d1
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/property-gcs14.d
@@ -0,0 +1,11 @@
+#name: GNU Property (input with gcs ouput forced with experimental-gcs experimental-gcs-report=warning)
+#source: property-gcs.s
+#alltargets: [check_shared_lib_support] *linux*
+#as: -march=armv9.4-a+gcs -defsym __mult__=0 -defsym __property_gcs__=1
+#ld: -z experimental-gcs -z experimental-gcs-report=warning
+#readelf: -n
+
+Displaying notes found in: .note.gnu.property
+[ 	]+Owner[ 	]+Data size[ 	]+Description
+  GNU                  0x00000010	NT_GNU_PROPERTY_TYPE_0
+      Properties: AArch64 feature: GCS
diff --git a/ld/testsuite/ld-aarch64/property-gcs15.d b/ld/testsuite/ld-aarch64/property-gcs15.d
new file mode 100644
index 0000000000000000000000000000000000000000..d1e723e0ea63648b6c32af6c3b7fdc50d405b12b
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/property-gcs15.d
@@ -0,0 +1,11 @@
+#name: GNU Property (input with gcs ouput forced with experimental-gcs experimental-gcs-report=error)
+#source: property-gcs.s
+#alltargets: [check_shared_lib_support] *linux*
+#as: -march=armv9.4-a+gcs -defsym __mult__=0 -defsym __property_gcs__=1
+#ld: -z experimental-gcs -z experimental-gcs-report=error
+#readelf: -n
+
+Displaying notes found in: .note.gnu.property
+[ 	]+Owner[ 	]+Data size[ 	]+Description
+  GNU                  0x00000010	NT_GNU_PROPERTY_TYPE_0
+      Properties: AArch64 feature: GCS
diff --git a/ld/testsuite/ld-aarch64/property-gcs16.d b/ld/testsuite/ld-aarch64/property-gcs16.d
new file mode 100644
index 0000000000000000000000000000000000000000..340577f17585ef5f0518e1cddce5d0ab2348b963
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/property-gcs16.d
@@ -0,0 +1,11 @@
+#name: GNU Property (input with gcs ouput forced with experimental-gcs=always experimental-gcs-report=none)
+#source: property-gcs.s
+#alltargets: [check_shared_lib_support] *linux*
+#as: -march=armv9.4-a+gcs -defsym __mult__=0 -defsym __property_gcs__=1
+#ld: -z experimental-gcs=always -z experimental-gcs-report=none
+#readelf: -n
+
+Displaying notes found in: .note.gnu.property
+[ 	]+Owner[ 	]+Data size[ 	]+Description
+  GNU                  0x00000010	NT_GNU_PROPERTY_TYPE_0
+      Properties: AArch64 feature: GCS
diff --git a/ld/testsuite/ld-aarch64/property-gcs17.d b/ld/testsuite/ld-aarch64/property-gcs17.d
new file mode 100644
index 0000000000000000000000000000000000000000..4ba9583ee925d1cd299799f2ae3ca8d2d8080f72
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/property-gcs17.d
@@ -0,0 +1,11 @@
+#name: GNU Property (input with gcs ouput forced with experimental-gcs=always experimental-gcs-report=warning)
+#source: property-gcs.s
+#alltargets: [check_shared_lib_support] *linux*
+#as: -march=armv9.4-a+gcs -defsym __mult__=0 -defsym __property_gcs__=1
+#ld: -z experimental-gcs=always -z experimental-gcs-report=warning
+#readelf: -n
+
+Displaying notes found in: .note.gnu.property
+[ 	]+Owner[ 	]+Data size[ 	]+Description
+  GNU                  0x00000010	NT_GNU_PROPERTY_TYPE_0
+      Properties: AArch64 feature: GCS
diff --git a/ld/testsuite/ld-aarch64/property-gcs18.d b/ld/testsuite/ld-aarch64/property-gcs18.d
new file mode 100644
index 0000000000000000000000000000000000000000..f71c10e252346bb9ca484770b27af5843facf229
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/property-gcs18.d
@@ -0,0 +1,11 @@
+#name: GNU Property (input with gcs ouput forced with experimental-gcs=always experimental-gcs-report=error)
+#source: property-gcs.s
+#alltargets: [check_shared_lib_support] *linux*
+#as: -march=armv9.4-a+gcs -defsym __mult__=0 -defsym __property_gcs__=1
+#ld: -z experimental-gcs=always -z experimental-gcs-report=error
+#readelf: -n
+
+Displaying notes found in: .note.gnu.property
+[ 	]+Owner[ 	]+Data size[ 	]+Description
+  GNU                  0x00000010	NT_GNU_PROPERTY_TYPE_0
+      Properties: AArch64 feature: GCS
diff --git a/ld/testsuite/ld-aarch64/property-gcs19.d b/ld/testsuite/ld-aarch64/property-gcs19.d
new file mode 100644
index 0000000000000000000000000000000000000000..468f96edcf17426d05782e2d9cec1dd125073b80
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/property-gcs19.d
@@ -0,0 +1,6 @@
+#name: GNU Property (input without gcs output forced with experimental-gcs=never)
+#source: property-gcs.s
+#alltargets: [check_shared_lib_support] *linux*
+#as: -march=armv9.4-a+gcs -defsym __mult__=0
+#ld: -z experimental-gcs=never
+#readelf: -n
diff --git a/ld/testsuite/ld-aarch64/property-gcs2.d b/ld/testsuite/ld-aarch64/property-gcs2.d
new file mode 100644
index 0000000000000000000000000000000000000000..ed545a180b30f4c11192da294d13fb883d24fb85
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/property-gcs2.d
@@ -0,0 +1,11 @@
+#name: GNU Property (input with gcs)
+#source: property-gcs.s
+#alltargets: [check_shared_lib_support] *linux*
+#as: -march=armv9.4-a+gcs -defsym __mult__=0 -defsym __property_gcs__=1
+#ld: -shared
+#readelf: -n
+
+Displaying notes found in: .note.gnu.property
+[ 	]+Owner[ 	]+Data size[ 	]+Description
+  GNU                  0x00000010	NT_GNU_PROPERTY_TYPE_0
+      Properties: AArch64 feature: GCS
diff --git a/ld/testsuite/ld-aarch64/property-gcs2.s b/ld/testsuite/ld-aarch64/property-gcs2.s
new file mode 100644
index 0000000000000000000000000000000000000000..6db7d8396c8668e66370fe456f13d47175da9147
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/property-gcs2.s
@@ -0,0 +1,33 @@
+	.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_gcs__
+	.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 0x4		/* GCS.  */
+4:
+	.p2align 3
+5:
+.endif
diff --git a/ld/testsuite/ld-aarch64/property-gcs20.d b/ld/testsuite/ld-aarch64/property-gcs20.d
new file mode 100644
index 0000000000000000000000000000000000000000..2bdff88a27ad49649b4fedd47eb72b46dc1fecec
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/property-gcs20.d
@@ -0,0 +1,6 @@
+#name: GNU Property (input without gcs output forced with experimental-gcs=implicit)
+#source: property-gcs.s
+#alltargets: [check_shared_lib_support] *linux*
+#as: -march=armv9.4-a+gcs -defsym __mult__=0
+#ld: -z experimental-gcs=implicit
+#readelf: -n
diff --git a/ld/testsuite/ld-aarch64/property-gcs21.d b/ld/testsuite/ld-aarch64/property-gcs21.d
new file mode 100644
index 0000000000000000000000000000000000000000..b42b11d14ea9445a3eac97ef9c9ac6da5be0bd6c
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/property-gcs21.d
@@ -0,0 +1,6 @@
+#name: GNU Property (input with gcs output forced with experimental-gcs=never)
+#source: property-gcs.s
+#alltargets: [check_shared_lib_support] *linux*
+#as: -march=armv9.4-a+gcs -defsym __mult__=0 -defsym __property_gcs__=1
+#ld: -z experimental-gcs=never
+#readelf: -n
diff --git a/ld/testsuite/ld-aarch64/property-gcs22.d b/ld/testsuite/ld-aarch64/property-gcs22.d
new file mode 100644
index 0000000000000000000000000000000000000000..431fc1ed35be7b19946b3207914f109540f43d07
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/property-gcs22.d
@@ -0,0 +1,11 @@
+#name: GNU Property (input with gcs output forced with experimental-gcs=implicit)
+#source: property-gcs.s
+#alltargets: [check_shared_lib_support] *linux*
+#as: -march=armv9.4-a+gcs -defsym __mult__=0 -defsym __property_gcs__=1
+#ld: -z experimental-gcs=implicit
+#readelf: -n
+
+Displaying notes found in: .note.gnu.property
+[ 	]+Owner[ 	]+Data size[ 	]+Description
+  GNU                  0x00000010	NT_GNU_PROPERTY_TYPE_0
+      Properties: AArch64 feature: GCS
diff --git a/ld/testsuite/ld-aarch64/property-gcs3.d b/ld/testsuite/ld-aarch64/property-gcs3.d
new file mode 100644
index 0000000000000000000000000000000000000000..68d50be08238cde54a2461163a0a22d64edcf69e
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/property-gcs3.d
@@ -0,0 +1,11 @@
+#name: GNU Property (input without gcs output forced with experimental-gcs)
+#source: property-gcs.s
+#alltargets: [check_shared_lib_support] *linux*
+#as: -march=armv9.4-a+gcs -defsym __mult__=0
+#ld: -z experimental-gcs
+#readelf: -n
+
+Displaying notes found in: .note.gnu.property
+[ 	]+Owner[ 	]+Data size[ 	]+Description
+  GNU                  0x00000010	NT_GNU_PROPERTY_TYPE_0
+      Properties: AArch64 feature: GCS
diff --git a/ld/testsuite/ld-aarch64/property-gcs4.d b/ld/testsuite/ld-aarch64/property-gcs4.d
new file mode 100644
index 0000000000000000000000000000000000000000..cd5711e3da35e895f5455a16eb757a87b5a490dc
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/property-gcs4.d
@@ -0,0 +1,11 @@
+#name: GNU Property (input without gcs ouput forced with experimental-gcs=always)
+#source: property-gcs.s
+#alltargets: [check_shared_lib_support] *linux*
+#as: -march=armv9.4-a+gcs -defsym __mult__=0
+#ld: -z experimental-gcs=always
+#readelf: -n
+
+Displaying notes found in: .note.gnu.property
+[ 	]+Owner[ 	]+Data size[ 	]+Description
+  GNU                  0x00000010	NT_GNU_PROPERTY_TYPE_0
+      Properties: AArch64 feature: GCS
diff --git a/ld/testsuite/ld-aarch64/property-gcs5.d b/ld/testsuite/ld-aarch64/property-gcs5.d
new file mode 100644
index 0000000000000000000000000000000000000000..b7a751c0276c6306805595edc08bb88e15e17e53
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/property-gcs5.d
@@ -0,0 +1,11 @@
+#name: GNU Property (input without gcs ouput forced with experimental-gcs experimental-gcs-report=none)
+#source: property-gcs.s
+#alltargets: [check_shared_lib_support] *linux*
+#as: -march=armv9.4-a+gcs -defsym __mult__=0
+#ld: -z experimental-gcs -z experimental-gcs-report=none
+#readelf: -n
+
+Displaying notes found in: .note.gnu.property
+[ 	]+Owner[ 	]+Data size[ 	]+Description
+  GNU                  0x00000010	NT_GNU_PROPERTY_TYPE_0
+      Properties: AArch64 feature: GCS
diff --git a/ld/testsuite/ld-aarch64/property-gcs6.d b/ld/testsuite/ld-aarch64/property-gcs6.d
new file mode 100644
index 0000000000000000000000000000000000000000..5abf8126d89e9e2c857f706abd8b9d19717c702a
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/property-gcs6.d
@@ -0,0 +1,12 @@
+#name: GNU Property (input without gcs ouput forced with experimental-gcs experimental-gcs-report=warning)
+#source: property-gcs.s
+#alltargets: [check_shared_lib_support] *linux*
+#as: -march=armv9.4-a+gcs -defsym __mult__=0
+#ld: -z experimental-gcs -z experimental-gcs-report=warning
+#readelf: -n
+#warning: .*property-gcs.*: warning: GCS turned on by -z experimental-gcs on the output when all inputs do not have GCS in NOTE section.
+
+Displaying notes found in: .note.gnu.property
+[ 	]+Owner[ 	]+Data size[ 	]+Description
+  GNU                  0x00000010	NT_GNU_PROPERTY_TYPE_0
+      Properties: AArch64 feature: GCS
diff --git a/ld/testsuite/ld-aarch64/property-gcs7.d b/ld/testsuite/ld-aarch64/property-gcs7.d
new file mode 100644
index 0000000000000000000000000000000000000000..4df5693a27b11544489d934de522bb3c621b3b20
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/property-gcs7.d
@@ -0,0 +1,6 @@
+#name: GNU Property (input without gcs ouput forced with experimental-gcs experimental-gcs-report=error)
+#source: property-gcs.s
+#alltargets: [check_shared_lib_support] *linux*
+#as: -march=armv9.4-a+gcs -defsym __mult__=0
+#ld: -z experimental-gcs -z experimental-gcs-report=error
+#error: .*property-gcs.*: error: GCS turned on by -z experimental-gcs on the output when all inputs do not have GCS in NOTE section.
diff --git a/ld/testsuite/ld-aarch64/property-gcs8.d b/ld/testsuite/ld-aarch64/property-gcs8.d
new file mode 100644
index 0000000000000000000000000000000000000000..463c3ad4197d87f15c724b33b5196911586d2c8f
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/property-gcs8.d
@@ -0,0 +1,11 @@
+#name: GNU Property (input without gcs ouput forced with experimental-gcs=always experimental-gcs-report=none)
+#source: property-gcs.s
+#alltargets: [check_shared_lib_support] *linux*
+#as: -march=armv9.4-a+gcs -defsym __mult__=0
+#ld: -z experimental-gcs=always -z experimental-gcs-report=none
+#readelf: -n
+
+Displaying notes found in: .note.gnu.property
+[ 	]+Owner[ 	]+Data size[ 	]+Description
+  GNU                  0x00000010	NT_GNU_PROPERTY_TYPE_0
+      Properties: AArch64 feature: GCS
diff --git a/ld/testsuite/ld-aarch64/property-gcs9.d b/ld/testsuite/ld-aarch64/property-gcs9.d
new file mode 100644
index 0000000000000000000000000000000000000000..c3083675c8fd5c26db5666f4153b2639737f83f7
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/property-gcs9.d
@@ -0,0 +1,12 @@
+#name: GNU Property (input without gcs ouput forced with experimental-gcs=always experimental-gcs-report=warning)
+#source: property-gcs.s
+#alltargets: [check_shared_lib_support] *linux*
+#as: -march=armv9.4-a+gcs -defsym __mult__=0
+#ld: -z experimental-gcs=always -z experimental-gcs-report=warning
+#readelf: -n
+#warning: .*property-gcs.*: warning: GCS turned on by -z experimental-gcs on the output when all inputs do not have GCS in NOTE section.
+
+Displaying notes found in: .note.gnu.property
+[ 	]+Owner[ 	]+Data size[ 	]+Description
+  GNU                  0x00000010	NT_GNU_PROPERTY_TYPE_0
+      Properties: AArch64 feature: GCS

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

* Re: [BFD, LD] aarch64: Add support for GCS in AArch64 linker.
  2024-01-04 17:23 [BFD, LD] aarch64: Add support for GCS in AArch64 linker Srinath Parvathaneni
@ 2024-01-05 10:57 ` Nick Clifton
  2024-01-30  9:13   ` [Committed][BFD, LD v2] " Srinath Parvathaneni
  0 siblings, 1 reply; 3+ messages in thread
From: Nick Clifton @ 2024-01-05 10:57 UTC (permalink / raw)
  To: Srinath Parvathaneni, binutils; +Cc: Richard Earnshaw

Hi Srinath,

> This patch will not be committed to development branch until the Kernel GCS
> ABI changes are approved and committed.
> 
> Ok to commit this patch to Arm vendor branch based on binutils-master ?

Yes.  (Since the branch is ARM specific, you do not really need to check
with us first, but the thought is appreciated).

Looking over the patch I did see one thing which niggled:

+     else if (strncmp (optarg, "experimental-gcs-report", 23) == 0)
+	{
+	  if (strlen (optarg) == 23 || strcmp (optarg + 23, "=none") == 0)
+	    gcs_report = GCS_NONE;
+	  else if (strcmp (optarg + 23, "=warning") == 0)
+	    gcs_report = GCS_WARN;
+	  else if (strcmp (optarg + 23, "=error") == 0)
+	    gcs_report = GCS_ERROR;
+	  else
+	    einfo (_("%P: error: unrecognized: `%s'\''\n"), optarg);
+	}
+     else if (strncmp (optarg, "experimental-gcs", 16) == 0)
+	{
+	  if (strlen (optarg) == 16 || strcmp (optarg + 16, "=always") == 0)
+	    gcs_type = GCS_ALWAYS;
+	  else if (strcmp (optarg + 16, "=never") == 0)
+	    gcs_type = GCS_NEVER;
+	  else if (strcmp (optarg + 16, "=implicit") == 0)
+	    gcs_type = GCS_IMPLICIT;
+	  else
+	    einfo (_("%P: error: unrecognized: `%s'\''\n"), optarg);
+	}

I do not like the use of magic numbers (23 and 16 in the fragment above).
Whilst it is fairly obvious where they come from, it is entirely possible
that a future coder might change one of the strings and not change (all
of) the places where the string's length is used.  So instead I would
suggest using constants instead, eg:

       static const char * egr = "experimental-gcs-report";
       const int egr_len = strlen (egr);

       else if (strncmp (optarg, egr, egr_len) == 0)
	{
	  if (strlen (optarg) == egr_len || strcmp (optarg + egr_len, "=none") == 0)
	    gcs_report = GCS_NONE;
	  else if (strcmp (optarg + egr_len, "=warning") == 0)
	    gcs_report = GCS_WARN;
	  else if (strcmp (optarg + egr_len, "=error") == 0)
	    gcs_report = GCS_ERROR;
	  else
	    einfo (_("%P: error: unrecognized: `%s'\''\n"), optarg);
	}

Cheers
   Nick


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

* [Committed][BFD, LD v2] aarch64: Add support for GCS in AArch64 linker.
  2024-01-05 10:57 ` Nick Clifton
@ 2024-01-30  9:13   ` Srinath Parvathaneni
  0 siblings, 0 replies; 3+ messages in thread
From: Srinath Parvathaneni @ 2024-01-30  9:13 UTC (permalink / raw)
  To: Nick Clifton, binutils; +Cc: Richard Earnshaw

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

Hi Nick,

On 1/5/24 10:57, Nick Clifton wrote:
> Hi Srinath,
> 
>> This patch will not be committed to development branch until the 
>> Kernel GCS
>> ABI changes are approved and committed.
>>
>> Ok to commit this patch to Arm vendor branch based on binutils-master ?
> 
> Yes.  (Since the branch is ARM specific, you do not really need to check
> with us first, but the thought is appreciated).

Thanks Nick, I made below proposed changes in v2 patch, created 
"users/ARM/gcs-binutils-gdb-master" branch and committed the patch 
(attached) to this branch.

Regards,
Srinath.

> Looking over the patch I did see one thing which niggled:
> 
> +     else if (strncmp (optarg, "experimental-gcs-report", 23) == 0)
> +    {
> +      if (strlen (optarg) == 23 || strcmp (optarg + 23, "=none") == 0)
> +        gcs_report = GCS_NONE;
> +      else if (strcmp (optarg + 23, "=warning") == 0)
> +        gcs_report = GCS_WARN;
> +      else if (strcmp (optarg + 23, "=error") == 0)
> +        gcs_report = GCS_ERROR;
> +      else
> +        einfo (_("%P: error: unrecognized: `%s'\''\n"), optarg);
> +    }
> +     else if (strncmp (optarg, "experimental-gcs", 16) == 0)
> +    {
> +      if (strlen (optarg) == 16 || strcmp (optarg + 16, "=always") == 0)
> +        gcs_type = GCS_ALWAYS;
> +      else if (strcmp (optarg + 16, "=never") == 0)
> +        gcs_type = GCS_NEVER;
> +      else if (strcmp (optarg + 16, "=implicit") == 0)
> +        gcs_type = GCS_IMPLICIT;
> +      else
> +        einfo (_("%P: error: unrecognized: `%s'\''\n"), optarg);
> +    }
> 
> I do not like the use of magic numbers (23 and 16 in the fragment above).
> Whilst it is fairly obvious where they come from, it is entirely possible
> that a future coder might change one of the strings and not change (all
> of) the places where the string's length is used.  So instead I would
> suggest using constants instead, eg:
> 
>        static const char * egr = "experimental-gcs-report";
>        const int egr_len = strlen (egr);
> 
>        else if (strncmp (optarg, egr, egr_len) == 0)
>      {
>        if (strlen (optarg) == egr_len || strcmp (optarg + egr_len, 
> "=none") == 0)
>          gcs_report = GCS_NONE;
>        else if (strcmp (optarg + egr_len, "=warning") == 0)
>          gcs_report = GCS_WARN;
>        else if (strcmp (optarg + egr_len, "=error") == 0)
>          gcs_report = GCS_ERROR;
>        else
>          einfo (_("%P: error: unrecognized: `%s'\''\n"), optarg);
>      }
> 
> Cheers
>    Nick
> 

[-- Attachment #2: gcs_linker.patch --]
[-- Type: text/x-patch, Size: 35720 bytes --]

diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c
index 109517db4aac3ec84611fabcf527ea9512439f4d..428f2c3507d1949aaf2cb7a3426a7b1da5fb7852 100644
--- a/bfd/elfnn-aarch64.c
+++ b/bfd/elfnn-aarch64.c
@@ -2546,6 +2546,12 @@ struct elf_aarch64_obj_tdata
      GNU_PROPERTY_AARCH64_FEATURE_1_BTI.  */
   int no_bti_warn;
 
+  /* Mark ouput with GCS based on -z experimental-gcs.  */
+  aarch64_gcs_type gcs_type;
+  /* Report linker warning/error for -z experimental-gcs-report based on
+     -z experimental-gcs.  */
+  aarch64_gcs_report gcs_report;
+
   /* PLT type based on security.  */
   aarch64_plt_type plt_type;
 };
@@ -5011,7 +5017,7 @@ bfd_elfNN_aarch64_set_options (struct bfd *output_bfd,
 			       int fix_erratum_835769,
 			       erratum_84319_opts fix_erratum_843419,
 			       int no_apply_dynamic_relocs,
-			       aarch64_bti_pac_info bp_info)
+			       aarch64_gnu_prop_info bp_info)
 {
   struct elf_aarch64_link_hash_table *globals;
 
@@ -5039,6 +5045,24 @@ bfd_elfNN_aarch64_set_options (struct bfd *output_bfd,
     default:
       break;
     }
+
+  switch (bp_info.gcs_type)
+    {
+    case GCS_ALWAYS:
+      elf_aarch64_tdata (output_bfd)->gnu_and_prop
+	|= GNU_PROPERTY_AARCH64_FEATURE_1_GCS;
+      break;
+    case GCS_NEVER:
+      elf_aarch64_tdata (output_bfd)->gnu_and_prop
+	&= ~GNU_PROPERTY_AARCH64_FEATURE_1_GCS;
+      break;
+
+    default:
+      break;
+    }
+
+  elf_aarch64_tdata (output_bfd)->gcs_type = bp_info.gcs_type;
+  elf_aarch64_tdata (output_bfd)->gcs_report = bp_info.gcs_report;
   elf_aarch64_tdata (output_bfd)->plt_type = bp_info.plt_type;
   setup_plt_values (link_info, bp_info.plt_type);
 }
@@ -10196,7 +10220,12 @@ 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);
+  aarch64_gcs_report gcs_report
+    = elf_aarch64_tdata (info->output_bfd)->gcs_report;
+  aarch64_gcs_report gcs_type
+    = elf_aarch64_tdata (info->output_bfd)->gcs_type;
+  bfd *pbfd = _bfd_aarch64_elf_link_setup_gnu_properties (info, &prop,
+							  gcs_report, gcs_type);
   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;
@@ -10215,30 +10244,54 @@ elfNN_aarch64_merge_gnu_properties (struct bfd_link_info *info,
 {
   uint32_t prop
     = elf_aarch64_tdata (info->output_bfd)->gnu_and_prop;
+  aarch64_gcs_report gcs_report
+    = elf_aarch64_tdata (info->output_bfd)->gcs_report;
+  aarch64_gcs_type gcs_type
+    = elf_aarch64_tdata (info->output_bfd)->gcs_type;
 
-  /* If output has been marked with BTI using command line argument, give out
-     warning if necessary.  */
   /* Properties are merged per type, hence only check for warnings when merging
      GNU_PROPERTY_AARCH64_FEATURE_1_AND.  */
-  if (((aprop && aprop->pr_type == GNU_PROPERTY_AARCH64_FEATURE_1_AND)
+  if ((aprop && aprop->pr_type == GNU_PROPERTY_AARCH64_FEATURE_1_AND)
 	|| (bprop && bprop->pr_type == GNU_PROPERTY_AARCH64_FEATURE_1_AND))
-      && (prop & GNU_PROPERTY_AARCH64_FEATURE_1_BTI)
-      && (!elf_aarch64_tdata (info->output_bfd)->no_bti_warn))
     {
-      if ((aprop && !(aprop->u.number & GNU_PROPERTY_AARCH64_FEATURE_1_BTI))
-	   || !aprop)
+      /* 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_bti_warn))
 	{
-	  _bfd_error_handler (_("%pB: warning: BTI turned on by -z force-bti when "
-				"all inputs do not have BTI in NOTE section."),
-			      abfd);
+	  if ((aprop && !(aprop->u.number & GNU_PROPERTY_AARCH64_FEATURE_1_BTI))
+	      || !aprop)
+	    {
+	      _bfd_error_handler (_("%pB: warning: BTI turned on by -z "
+				  "force-bti when all inputs do not have BTI "
+				  "in NOTE section."), abfd);
+	    }
+	  if ((bprop && !(bprop->u.number & GNU_PROPERTY_AARCH64_FEATURE_1_BTI))
+	      || !bprop)
+	    {
+	      _bfd_error_handler (_("%pB: warning: BTI turned on by -z "
+				  "force-bti when all inputs do not have BTI "
+				  "in NOTE section."), bbfd);
+	    }
 	}
-      if ((bprop && !(bprop->u.number & GNU_PROPERTY_AARCH64_FEATURE_1_BTI))
-	   || !bprop)
+
+      /* If output has been marked with GCS using -z experimental-gcs and input
+	 is missing GCS marking throw warning/error on
+	 -z experimental-gcs-report=warning/error.  */
+      if ((prop & GNU_PROPERTY_AARCH64_FEATURE_1_GCS) && gcs_report != GCS_NONE)
 	{
-	  _bfd_error_handler (_("%pB: warning: BTI turned on by -z force-bti when "
-				"all inputs do not have BTI in NOTE section."),
-			      bbfd);
+	  if ((aprop && !(aprop->u.number & GNU_PROPERTY_AARCH64_FEATURE_1_GCS))
+	      || !aprop)
+	    _bfd_aarch64_elf_check_gcs_report (gcs_report, abfd);
+	  if ((bprop && !(bprop->u.number & GNU_PROPERTY_AARCH64_FEATURE_1_GCS))
+	      || !bprop)
+	    _bfd_aarch64_elf_check_gcs_report (gcs_report, bbfd);
 	}
+
+      if (gcs_type == GCS_NEVER && aprop != NULL)
+	aprop->u.number &= ~GNU_PROPERTY_AARCH64_FEATURE_1_GCS;
+      if (gcs_type == GCS_NEVER && bprop != NULL)
+	bprop->u.number &= ~GNU_PROPERTY_AARCH64_FEATURE_1_GCS;
     }
 
   return  _bfd_aarch64_elf_merge_gnu_properties (info, abfd, aprop,
diff --git a/bfd/elfxx-aarch64.h b/bfd/elfxx-aarch64.h
index 6c084f757963b0cf7ccc4e7970d571b9c5edfdd7..ca523d81df13619ebdcef462b3ef24f611305a7c 100644
--- a/bfd/elfxx-aarch64.h
+++ b/bfd/elfxx-aarch64.h
@@ -46,6 +46,27 @@ typedef enum
   BTI_WARN	= 1,  /* BTI is enabled with -z force-bti.  */
 } aarch64_enable_bti_type;
 
+/* To indicate whether GNU_PROPERTY_AARCH64_FEATURE_1_GCS bit is
+   enabled/disabled on the output when -z experimental-gcs linker
+   command line option is passed.  */
+typedef enum
+{
+  GCS_NEVER	= 0,  /* gcs is disabled on output.  */
+  GCS_IMPLICIT  = 1,  /* gcs is deduced from input object.  */
+  GCS_ALWAYS	= 2,  /* gsc is enabled on output.  */
+} aarch64_gcs_type;
+
+/* To indicate whether to generate linker warning/errors for
+   -z experimental-gcs-report when -z experimental-gcs=always is passed.  */
+typedef enum
+{
+  GCS_NONE	= 0,  /* Does not emit any warning/error messages.  */
+  GCS_WARN	= 1,  /* Emit warning when the input objects are missing gcs
+			 markings and output have gcs marking.  */
+  GCS_ERROR	= 2,  /* Emit error when the input objects are missing gcs
+			 markings and output have gcs marking.  */
+} aarch64_gcs_report;
+
 /* 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
@@ -54,7 +75,9 @@ typedef struct
 {
   aarch64_plt_type plt_type;
   aarch64_enable_bti_type bti_type;
-} aarch64_bti_pac_info;
+  aarch64_gcs_type gcs_type;
+  aarch64_gcs_report gcs_report;
+} aarch64_gnu_prop_info;
 
 /* An enum to define what kind of erratum fixes we should apply.  This gives the
    user a bit more control over the sequences we generate.  */
@@ -67,11 +90,11 @@ typedef enum
 
 extern void bfd_elf64_aarch64_set_options
   (bfd *, struct bfd_link_info *, int, int, int, int, erratum_84319_opts, int,
-   aarch64_bti_pac_info);
+   aarch64_gnu_prop_info);
 
 extern void bfd_elf32_aarch64_set_options
   (bfd *, struct bfd_link_info *, int, int, int, int, erratum_84319_opts, int,
-   aarch64_bti_pac_info);
+   aarch64_gnu_prop_info);
 
 /* AArch64 stub generation support for ELF64.  Called from the linker.  */
 extern int elf64_aarch64_setup_section_lists
@@ -135,8 +158,9 @@ _bfd_aarch64_elf_write_core_note (bfd *, char *, int *, int, ...);
 #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 *);
+_bfd_aarch64_elf_link_setup_gnu_properties (struct bfd_link_info *, uint32_t *,
+					    aarch64_gcs_report,
+					    aarch64_gcs_type);
 
 extern enum elf_property_kind
 _bfd_aarch64_elf_parse_gnu_properties (bfd *, unsigned int,
@@ -146,6 +170,8 @@ extern bool
 _bfd_aarch64_elf_merge_gnu_properties (struct bfd_link_info *, bfd *,
 				       elf_property *, elf_property *,
 				       uint32_t);
+extern void
+_bfd_aarch64_elf_check_gcs_report (aarch64_gcs_report, bfd *);
 
 extern void
 _bfd_aarch64_elf_link_fixup_gnu_properties (struct bfd_link_info *,
diff --git a/bfd/elfxx-aarch64.c b/bfd/elfxx-aarch64.c
index d1279adc2e4c0f5e86d890747ac33a6e49803fc8..dd64f2067ac98d2e39659858ca42e082dd9aeae6 100644
--- a/bfd/elfxx-aarch64.c
+++ b/bfd/elfxx-aarch64.c
@@ -702,7 +702,9 @@ _bfd_aarch64_elf_write_core_note (bfd *abfd, char *buf, int *bufsiz, int note_ty
    GPROP accordingly.  */
 bfd *
 _bfd_aarch64_elf_link_setup_gnu_properties (struct bfd_link_info *info,
-					    uint32_t *gprop)
+					    uint32_t *gprop,
+					    aarch64_gcs_report gcs_report,
+					    aarch64_gcs_type gcs_type)
 {
   asection *sec;
   bfd *pbfd;
@@ -738,6 +740,11 @@ _bfd_aarch64_elf_link_setup_gnu_properties (struct bfd_link_info *info,
 	    _bfd_error_handler (_("%pB: warning: BTI turned on by -z force-bti "
 				  "when all inputs do not have BTI in NOTE "
 				  "section."), ebfd);
+
+      if ((gnu_prop & GNU_PROPERTY_AARCH64_FEATURE_1_GCS)
+	  && !(prop->u.number & GNU_PROPERTY_AARCH64_FEATURE_1_GCS))
+	_bfd_aarch64_elf_check_gcs_report (gcs_report, ebfd);
+
       prop->u.number |= gnu_prop;
       prop->pr_kind = property_number;
 
@@ -765,6 +772,14 @@ _bfd_aarch64_elf_link_setup_gnu_properties (struct bfd_link_info *info,
 	  elf_section_type (sec) = SHT_NOTE;
 	}
     }
+  else if (ebfd != NULL && gcs_type == GCS_NEVER)
+    {
+      prop = _bfd_elf_get_property (ebfd, GNU_PROPERTY_AARCH64_FEATURE_1_AND,
+				    4);
+      prop->u.number &= ~GNU_PROPERTY_AARCH64_FEATURE_1_GCS;
+      if (prop->u.number == 0)
+	prop->pr_kind = property_remove;
+    }
 
   pbfd = _bfd_elf_link_setup_gnu_properties (info);
 
@@ -785,7 +800,8 @@ _bfd_aarch64_elf_link_setup_gnu_properties (struct bfd_link_info *info,
 	    {
 	      gnu_prop = (p->property.u.number
 			  & (GNU_PROPERTY_AARCH64_FEATURE_1_PAC
-			      | GNU_PROPERTY_AARCH64_FEATURE_1_BTI));
+			      | GNU_PROPERTY_AARCH64_FEATURE_1_BTI
+			      | GNU_PROPERTY_AARCH64_FEATURE_1_GCS));
 	      break;
 	    }
 	  else if (GNU_PROPERTY_AARCH64_FEATURE_1_AND < p->property.pr_type)
@@ -922,3 +938,20 @@ _bfd_aarch64_elf_link_fixup_gnu_properties
 	}
     }
 }
+
+/* Check AArch64 GCS report.  */
+void
+_bfd_aarch64_elf_check_gcs_report (aarch64_gcs_report gcs_report, bfd *ebfd)
+{
+  if (gcs_report == GCS_WARN)
+    _bfd_error_handler (_("%pB: warning: GCS turned on by -z experimental-gcs "
+			"on the output when all inputs do not have GCS in NOTE "
+			"section."), ebfd);
+  else if (gcs_report == GCS_ERROR)
+    {
+      _bfd_error_handler (_("%pB: error: GCS turned on by -z experimental-gcs "
+			  "on the output when all inputs do not have GCS in "
+			  "NOTE section."), ebfd);
+      _exit (EXIT_FAILURE);
+    }
+}
diff --git a/binutils/readelf.c b/binutils/readelf.c
index 5e4ad6ea6add5742ac3df8c62f4662a68bfb0963..794cbb77a9c178e808d7dc3f2dd566830a61d3c3 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -20636,6 +20636,10 @@ decode_aarch64_feature_1_and (unsigned int bitmask)
 	  printf ("PAC");
 	  break;
 
+	case GNU_PROPERTY_AARCH64_FEATURE_1_GCS:
+	  printf ("GCS");
+	  break;
+
 	default:
 	  printf (_("<unknown: %x>"), bit);
 	  break;
diff --git a/include/elf/common.h b/include/elf/common.h
index 6a66456cd2274dc1af7d210649916babdb49e7b4..289b8821b7de74e48fef5601cf5eb6637e3972b8 100644
--- a/include/elf/common.h
+++ b/include/elf/common.h
@@ -1001,6 +1001,7 @@
 
 #define GNU_PROPERTY_AARCH64_FEATURE_1_BTI	(1U << 0)
 #define GNU_PROPERTY_AARCH64_FEATURE_1_PAC	(1U << 1)
+#define GNU_PROPERTY_AARCH64_FEATURE_1_GCS	(1U << 2)
 
 /* Values used in GNU .note.ABI-tag notes (NT_GNU_ABI_TAG).  */
 #define GNU_ABI_TAG_LINUX	0
diff --git a/ld/emultempl/aarch64elf.em b/ld/emultempl/aarch64elf.em
index b647909ae63d59de20baff98465358a9810723ee..fb331e0655318e3cdf1da427ccb6439f96d1395a 100644
--- a/ld/emultempl/aarch64elf.em
+++ b/ld/emultempl/aarch64elf.em
@@ -36,6 +36,12 @@ static erratum_84319_opts fix_erratum_843419 = ERRAT_NONE;
 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 aarch64_gcs_type gcs_type = GCS_IMPLICIT;
+static aarch64_gcs_report gcs_report = GCS_NONE;
+static const char * egr = "experimental-gcs-report";
+static const char * eg = "experimental-gcs";
+#define EGR_LEN strlen (egr)
+#define EG_LEN strlen (eg)
 
 static void
 gld${EMULATION_NAME}_before_parse (void)
@@ -321,9 +327,11 @@ aarch64_elf_create_output_section_statements (void)
       return;
     }
 
-  aarch64_bti_pac_info bp_info;
+  aarch64_gnu_prop_info bp_info;
   bp_info.plt_type = plt_type;
   bp_info.bti_type = bti_type;
+  bp_info.gcs_type = gcs_type;
+  bp_info.gcs_report = gcs_report;
 
   bfd_elf${ELFSIZE}_aarch64_set_options (link_info.output_bfd, &link_info,
 				 no_enum_size_warning,
@@ -408,6 +416,19 @@ PARSE_AND_LIST_OPTIONS='
   fprintf (file, _("  --no-apply-dynamic-relocs    Do not apply link-time values for dynamic relocations\n"));
   fprintf (file, _("  -z force-bti                  Turn on Branch Target Identification mechanism and generate PLTs with BTI. Generate warnings for missing BTI on inputs\n"));
   fprintf (file, _("  -z pac-plt                    Protect PLTs with Pointer Authentication.\n"));
+  fprintf (file, _("\
+  -z experimental-gcs[=always|never|implicit]		Turn on Guarded Control Stack(gcs) mechanism on the output.\n\
+							implicit(default): deduce gcs from input objects.\n\
+							always: always marks the output with gcs.\n\
+							never: never marks the output with gcs.\n"));
+  fprintf (file, _("\
+  -z experimental-gcs-report[=none|warning|error]	Emit warning/error on mismatch of gcs marking between input objects and ouput.\n\
+							none (default): Does not emit any warning/error messages.\n\
+							warning: Emit warning when the input objects are missing gcs markings\n\
+								 and output have gcs marking.\n\
+							error: Emit error when the input objects are missing gcs markings\n\
+							       and output have gcs marking.\n"));
+
 '
 
 PARSE_AND_LIST_ARGS_CASE_Z_AARCH64='
@@ -418,6 +439,28 @@ PARSE_AND_LIST_ARGS_CASE_Z_AARCH64='
 	}
       else if (strcmp (optarg, "pac-plt") == 0)
 	plt_type |= PLT_PAC;
+     else if (strncmp (optarg, egr, EGR_LEN) == 0)
+	{
+	  if (strlen (optarg) == EGR_LEN || strcmp (optarg + EGR_LEN, "=none") == 0)
+	    gcs_report = GCS_NONE;
+	  else if (strcmp (optarg + EGR_LEN, "=warning") == 0)
+	    gcs_report = GCS_WARN;
+	  else if (strcmp (optarg + EGR_LEN, "=error") == 0)
+	    gcs_report = GCS_ERROR;
+	  else
+	    einfo (_("%P: error: unrecognized: `%s'\''\n"), optarg);
+	}
+     else if (strncmp (optarg, eg, EG_LEN) == 0)
+	{
+	  if (strlen (optarg) == EG_LEN || strcmp (optarg + EG_LEN, "=always") == 0)
+	    gcs_type = GCS_ALWAYS;
+	  else if (strcmp (optarg + EG_LEN, "=never") == 0)
+	    gcs_type = GCS_NEVER;
+	  else if (strcmp (optarg + EG_LEN, "=implicit") == 0)
+	    gcs_type = GCS_IMPLICIT;
+	  else
+	    einfo (_("%P: error: unrecognized: `%s'\''\n"), optarg);
+	}
 '
 PARSE_AND_LIST_ARGS_CASE_Z="$PARSE_AND_LIST_ARGS_CASE_Z $PARSE_AND_LIST_ARGS_CASE_Z_AARCH64"
 
diff --git a/ld/testsuite/ld-aarch64/aarch64-elf.exp b/ld/testsuite/ld-aarch64/aarch64-elf.exp
index 9ce61579e6c5d2512278e54324fc8add486b0844..31abc5a07d8c51eb85f41f7fc8d64a4bf4fc7662 100644
--- a/ld/testsuite/ld-aarch64/aarch64-elf.exp
+++ b/ld/testsuite/ld-aarch64/aarch64-elf.exp
@@ -471,3 +471,26 @@ run_dump_test_lp64 "bti-far-3"
 if { ![skip_sframe_tests] } {
   run_dump_test "sframe-simple-1"
 }
+
+run_dump_test "property-gcs1"
+run_dump_test "property-gcs2"
+run_dump_test "property-gcs3"
+run_dump_test "property-gcs4"
+run_dump_test "property-gcs5"
+run_dump_test "property-gcs6"
+run_dump_test "property-gcs7"
+run_dump_test "property-gcs8"
+run_dump_test "property-gcs9"
+run_dump_test "property-gcs10"
+run_dump_test "property-gcs11"
+run_dump_test "property-gcs12"
+run_dump_test "property-gcs13"
+run_dump_test "property-gcs14"
+run_dump_test "property-gcs15"
+run_dump_test "property-gcs16"
+run_dump_test "property-gcs17"
+run_dump_test "property-gcs18"
+run_dump_test "property-gcs19"
+run_dump_test "property-gcs20"
+run_dump_test "property-gcs21"
+run_dump_test "property-gcs22"
diff --git a/ld/testsuite/ld-aarch64/property-bti-pac1.d b/ld/testsuite/ld-aarch64/property-bti-pac1.d
index 59fa695165aa2fff603c2d4156c284bf08e2c072..c28a0cbf850f4dee288901c84047ba3c55611ea7 100644
--- a/ld/testsuite/ld-aarch64/property-bti-pac1.d
+++ b/ld/testsuite/ld-aarch64/property-bti-pac1.d
@@ -8,4 +8,4 @@
 Displaying notes found in: .note.gnu.property
 [ 	]+Owner[ 	]+Data size[ 	]+Description
   GNU                  0x00000010	NT_GNU_PROPERTY_TYPE_0
-      Properties: AArch64 feature: BTI, PAC
+      Properties: AArch64 feature: BTI, PAC, GCS
diff --git a/ld/testsuite/ld-aarch64/property-bti-pac1.s b/ld/testsuite/ld-aarch64/property-bti-pac1.s
index 414c9277f1dabc5fdc08b8b71716c44ea8bc8343..42156917d587491fafe6de575669166c7c9459be 100644
--- a/ld/testsuite/ld-aarch64/property-bti-pac1.s
+++ b/ld/testsuite/ld-aarch64/property-bti-pac1.s
@@ -12,6 +12,20 @@ _start:
 	.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 0x4		/* GCS.  */
+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.  */
diff --git a/ld/testsuite/ld-aarch64/property-gcs.s b/ld/testsuite/ld-aarch64/property-gcs.s
new file mode 100644
index 0000000000000000000000000000000000000000..bc7e66e89338a94ef2bfe68bb20671e896404e93
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/property-gcs.s
@@ -0,0 +1,25 @@
+	.text
+	.globl _start
+	.type _start,@function
+_start:
+	mov x1, #2
+.ifndef __mult__
+	bl foo
+.endif
+.ifdef __property_gcs__
+	.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 0x4		/* GCS.  */
+4:
+	.p2align 3
+5:
+.endif
diff --git a/ld/testsuite/ld-aarch64/property-gcs1.d b/ld/testsuite/ld-aarch64/property-gcs1.d
new file mode 100644
index 0000000000000000000000000000000000000000..c724ac56ca3f612ad2b109d465918990fcfee8f8
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/property-gcs1.d
@@ -0,0 +1,6 @@
+#name: GNU Property (input without gcs)
+#source: property-gcs.s
+#alltargets: [check_shared_lib_support] *linux*
+#as: -march=armv9.4-a+gcs -defsym __mult__=0
+#ld: -shared
+#readelf: -n
diff --git a/ld/testsuite/ld-aarch64/property-gcs10.d b/ld/testsuite/ld-aarch64/property-gcs10.d
new file mode 100644
index 0000000000000000000000000000000000000000..4b6deedc0c205aaaf30414c5586ecfe1ba4dcf8b
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/property-gcs10.d
@@ -0,0 +1,6 @@
+#name: GNU Property (input without gcs ouput forced with experimental-gcs=always experimental-gcs-report=error)
+#source: property-gcs.s
+#alltargets: [check_shared_lib_support] *linux*
+#as: -march=armv9.4-a+gcs -defsym __mult__=0
+#ld: -z experimental-gcs=always -z experimental-gcs-report=error
+#error: .*property-gcs.*: error: GCS turned on by -z experimental-gcs on the output when all inputs do not have GCS in NOTE section.
diff --git a/ld/testsuite/ld-aarch64/property-gcs11.d b/ld/testsuite/ld-aarch64/property-gcs11.d
new file mode 100644
index 0000000000000000000000000000000000000000..8abacf28eb1bbaa179ddbd9ff08753c844eca7c1
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/property-gcs11.d
@@ -0,0 +1,11 @@
+#name: GNU Property (input with gcs output forced with experimental-gcs)
+#source: property-gcs.s
+#alltargets: [check_shared_lib_support] *linux*
+#as: -march=armv9.4-a+gcs -defsym __mult__=0 -defsym __property_gcs__=1
+#ld: -z experimental-gcs
+#readelf: -n
+
+Displaying notes found in: .note.gnu.property
+[ 	]+Owner[ 	]+Data size[ 	]+Description
+  GNU                  0x00000010	NT_GNU_PROPERTY_TYPE_0
+      Properties: AArch64 feature: GCS
diff --git a/ld/testsuite/ld-aarch64/property-gcs12.d b/ld/testsuite/ld-aarch64/property-gcs12.d
new file mode 100644
index 0000000000000000000000000000000000000000..0fe246dfa3a75972be0d3cce32d30a8d5305855e
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/property-gcs12.d
@@ -0,0 +1,11 @@
+#name: GNU Property (input with gcs ouput forced with experimental-gcs=always)
+#source: property-gcs.s
+#alltargets: [check_shared_lib_support] *linux*
+#as: -march=armv9.4-a+gcs -defsym __mult__=0 -defsym __property_gcs__=1
+#ld: -z experimental-gcs=always
+#readelf: -n
+
+Displaying notes found in: .note.gnu.property
+[ 	]+Owner[ 	]+Data size[ 	]+Description
+  GNU                  0x00000010	NT_GNU_PROPERTY_TYPE_0
+      Properties: AArch64 feature: GCS
diff --git a/ld/testsuite/ld-aarch64/property-gcs13.d b/ld/testsuite/ld-aarch64/property-gcs13.d
new file mode 100644
index 0000000000000000000000000000000000000000..c6077aeaa5ace7a7f467b8bef45f7fa2de733fee
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/property-gcs13.d
@@ -0,0 +1,11 @@
+#name: GNU Property (input with gcs ouput forced with experimental-gcs experimental-gcs-report=none)
+#source: property-gcs.s
+#alltargets: [check_shared_lib_support] *linux*
+#as: -march=armv9.4-a+gcs -defsym __mult__=0 -defsym __property_gcs__=1
+#ld: -z experimental-gcs -z experimental-gcs-report=none
+#readelf: -n
+
+Displaying notes found in: .note.gnu.property
+[ 	]+Owner[ 	]+Data size[ 	]+Description
+  GNU                  0x00000010	NT_GNU_PROPERTY_TYPE_0
+      Properties: AArch64 feature: GCS
diff --git a/ld/testsuite/ld-aarch64/property-gcs14.d b/ld/testsuite/ld-aarch64/property-gcs14.d
new file mode 100644
index 0000000000000000000000000000000000000000..0f7490ef4a5d638aaad4d301f63cb20cfd86b1d1
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/property-gcs14.d
@@ -0,0 +1,11 @@
+#name: GNU Property (input with gcs ouput forced with experimental-gcs experimental-gcs-report=warning)
+#source: property-gcs.s
+#alltargets: [check_shared_lib_support] *linux*
+#as: -march=armv9.4-a+gcs -defsym __mult__=0 -defsym __property_gcs__=1
+#ld: -z experimental-gcs -z experimental-gcs-report=warning
+#readelf: -n
+
+Displaying notes found in: .note.gnu.property
+[ 	]+Owner[ 	]+Data size[ 	]+Description
+  GNU                  0x00000010	NT_GNU_PROPERTY_TYPE_0
+      Properties: AArch64 feature: GCS
diff --git a/ld/testsuite/ld-aarch64/property-gcs15.d b/ld/testsuite/ld-aarch64/property-gcs15.d
new file mode 100644
index 0000000000000000000000000000000000000000..d1e723e0ea63648b6c32af6c3b7fdc50d405b12b
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/property-gcs15.d
@@ -0,0 +1,11 @@
+#name: GNU Property (input with gcs ouput forced with experimental-gcs experimental-gcs-report=error)
+#source: property-gcs.s
+#alltargets: [check_shared_lib_support] *linux*
+#as: -march=armv9.4-a+gcs -defsym __mult__=0 -defsym __property_gcs__=1
+#ld: -z experimental-gcs -z experimental-gcs-report=error
+#readelf: -n
+
+Displaying notes found in: .note.gnu.property
+[ 	]+Owner[ 	]+Data size[ 	]+Description
+  GNU                  0x00000010	NT_GNU_PROPERTY_TYPE_0
+      Properties: AArch64 feature: GCS
diff --git a/ld/testsuite/ld-aarch64/property-gcs16.d b/ld/testsuite/ld-aarch64/property-gcs16.d
new file mode 100644
index 0000000000000000000000000000000000000000..340577f17585ef5f0518e1cddce5d0ab2348b963
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/property-gcs16.d
@@ -0,0 +1,11 @@
+#name: GNU Property (input with gcs ouput forced with experimental-gcs=always experimental-gcs-report=none)
+#source: property-gcs.s
+#alltargets: [check_shared_lib_support] *linux*
+#as: -march=armv9.4-a+gcs -defsym __mult__=0 -defsym __property_gcs__=1
+#ld: -z experimental-gcs=always -z experimental-gcs-report=none
+#readelf: -n
+
+Displaying notes found in: .note.gnu.property
+[ 	]+Owner[ 	]+Data size[ 	]+Description
+  GNU                  0x00000010	NT_GNU_PROPERTY_TYPE_0
+      Properties: AArch64 feature: GCS
diff --git a/ld/testsuite/ld-aarch64/property-gcs17.d b/ld/testsuite/ld-aarch64/property-gcs17.d
new file mode 100644
index 0000000000000000000000000000000000000000..4ba9583ee925d1cd299799f2ae3ca8d2d8080f72
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/property-gcs17.d
@@ -0,0 +1,11 @@
+#name: GNU Property (input with gcs ouput forced with experimental-gcs=always experimental-gcs-report=warning)
+#source: property-gcs.s
+#alltargets: [check_shared_lib_support] *linux*
+#as: -march=armv9.4-a+gcs -defsym __mult__=0 -defsym __property_gcs__=1
+#ld: -z experimental-gcs=always -z experimental-gcs-report=warning
+#readelf: -n
+
+Displaying notes found in: .note.gnu.property
+[ 	]+Owner[ 	]+Data size[ 	]+Description
+  GNU                  0x00000010	NT_GNU_PROPERTY_TYPE_0
+      Properties: AArch64 feature: GCS
diff --git a/ld/testsuite/ld-aarch64/property-gcs18.d b/ld/testsuite/ld-aarch64/property-gcs18.d
new file mode 100644
index 0000000000000000000000000000000000000000..f71c10e252346bb9ca484770b27af5843facf229
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/property-gcs18.d
@@ -0,0 +1,11 @@
+#name: GNU Property (input with gcs ouput forced with experimental-gcs=always experimental-gcs-report=error)
+#source: property-gcs.s
+#alltargets: [check_shared_lib_support] *linux*
+#as: -march=armv9.4-a+gcs -defsym __mult__=0 -defsym __property_gcs__=1
+#ld: -z experimental-gcs=always -z experimental-gcs-report=error
+#readelf: -n
+
+Displaying notes found in: .note.gnu.property
+[ 	]+Owner[ 	]+Data size[ 	]+Description
+  GNU                  0x00000010	NT_GNU_PROPERTY_TYPE_0
+      Properties: AArch64 feature: GCS
diff --git a/ld/testsuite/ld-aarch64/property-gcs19.d b/ld/testsuite/ld-aarch64/property-gcs19.d
new file mode 100644
index 0000000000000000000000000000000000000000..468f96edcf17426d05782e2d9cec1dd125073b80
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/property-gcs19.d
@@ -0,0 +1,6 @@
+#name: GNU Property (input without gcs output forced with experimental-gcs=never)
+#source: property-gcs.s
+#alltargets: [check_shared_lib_support] *linux*
+#as: -march=armv9.4-a+gcs -defsym __mult__=0
+#ld: -z experimental-gcs=never
+#readelf: -n
diff --git a/ld/testsuite/ld-aarch64/property-gcs2.d b/ld/testsuite/ld-aarch64/property-gcs2.d
new file mode 100644
index 0000000000000000000000000000000000000000..ed545a180b30f4c11192da294d13fb883d24fb85
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/property-gcs2.d
@@ -0,0 +1,11 @@
+#name: GNU Property (input with gcs)
+#source: property-gcs.s
+#alltargets: [check_shared_lib_support] *linux*
+#as: -march=armv9.4-a+gcs -defsym __mult__=0 -defsym __property_gcs__=1
+#ld: -shared
+#readelf: -n
+
+Displaying notes found in: .note.gnu.property
+[ 	]+Owner[ 	]+Data size[ 	]+Description
+  GNU                  0x00000010	NT_GNU_PROPERTY_TYPE_0
+      Properties: AArch64 feature: GCS
diff --git a/ld/testsuite/ld-aarch64/property-gcs2.s b/ld/testsuite/ld-aarch64/property-gcs2.s
new file mode 100644
index 0000000000000000000000000000000000000000..6db7d8396c8668e66370fe456f13d47175da9147
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/property-gcs2.s
@@ -0,0 +1,33 @@
+	.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_gcs__
+	.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 0x4		/* GCS.  */
+4:
+	.p2align 3
+5:
+.endif
diff --git a/ld/testsuite/ld-aarch64/property-gcs20.d b/ld/testsuite/ld-aarch64/property-gcs20.d
new file mode 100644
index 0000000000000000000000000000000000000000..2bdff88a27ad49649b4fedd47eb72b46dc1fecec
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/property-gcs20.d
@@ -0,0 +1,6 @@
+#name: GNU Property (input without gcs output forced with experimental-gcs=implicit)
+#source: property-gcs.s
+#alltargets: [check_shared_lib_support] *linux*
+#as: -march=armv9.4-a+gcs -defsym __mult__=0
+#ld: -z experimental-gcs=implicit
+#readelf: -n
diff --git a/ld/testsuite/ld-aarch64/property-gcs21.d b/ld/testsuite/ld-aarch64/property-gcs21.d
new file mode 100644
index 0000000000000000000000000000000000000000..b42b11d14ea9445a3eac97ef9c9ac6da5be0bd6c
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/property-gcs21.d
@@ -0,0 +1,6 @@
+#name: GNU Property (input with gcs output forced with experimental-gcs=never)
+#source: property-gcs.s
+#alltargets: [check_shared_lib_support] *linux*
+#as: -march=armv9.4-a+gcs -defsym __mult__=0 -defsym __property_gcs__=1
+#ld: -z experimental-gcs=never
+#readelf: -n
diff --git a/ld/testsuite/ld-aarch64/property-gcs22.d b/ld/testsuite/ld-aarch64/property-gcs22.d
new file mode 100644
index 0000000000000000000000000000000000000000..431fc1ed35be7b19946b3207914f109540f43d07
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/property-gcs22.d
@@ -0,0 +1,11 @@
+#name: GNU Property (input with gcs output forced with experimental-gcs=implicit)
+#source: property-gcs.s
+#alltargets: [check_shared_lib_support] *linux*
+#as: -march=armv9.4-a+gcs -defsym __mult__=0 -defsym __property_gcs__=1
+#ld: -z experimental-gcs=implicit
+#readelf: -n
+
+Displaying notes found in: .note.gnu.property
+[ 	]+Owner[ 	]+Data size[ 	]+Description
+  GNU                  0x00000010	NT_GNU_PROPERTY_TYPE_0
+      Properties: AArch64 feature: GCS
diff --git a/ld/testsuite/ld-aarch64/property-gcs3.d b/ld/testsuite/ld-aarch64/property-gcs3.d
new file mode 100644
index 0000000000000000000000000000000000000000..68d50be08238cde54a2461163a0a22d64edcf69e
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/property-gcs3.d
@@ -0,0 +1,11 @@
+#name: GNU Property (input without gcs output forced with experimental-gcs)
+#source: property-gcs.s
+#alltargets: [check_shared_lib_support] *linux*
+#as: -march=armv9.4-a+gcs -defsym __mult__=0
+#ld: -z experimental-gcs
+#readelf: -n
+
+Displaying notes found in: .note.gnu.property
+[ 	]+Owner[ 	]+Data size[ 	]+Description
+  GNU                  0x00000010	NT_GNU_PROPERTY_TYPE_0
+      Properties: AArch64 feature: GCS
diff --git a/ld/testsuite/ld-aarch64/property-gcs4.d b/ld/testsuite/ld-aarch64/property-gcs4.d
new file mode 100644
index 0000000000000000000000000000000000000000..cd5711e3da35e895f5455a16eb757a87b5a490dc
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/property-gcs4.d
@@ -0,0 +1,11 @@
+#name: GNU Property (input without gcs ouput forced with experimental-gcs=always)
+#source: property-gcs.s
+#alltargets: [check_shared_lib_support] *linux*
+#as: -march=armv9.4-a+gcs -defsym __mult__=0
+#ld: -z experimental-gcs=always
+#readelf: -n
+
+Displaying notes found in: .note.gnu.property
+[ 	]+Owner[ 	]+Data size[ 	]+Description
+  GNU                  0x00000010	NT_GNU_PROPERTY_TYPE_0
+      Properties: AArch64 feature: GCS
diff --git a/ld/testsuite/ld-aarch64/property-gcs5.d b/ld/testsuite/ld-aarch64/property-gcs5.d
new file mode 100644
index 0000000000000000000000000000000000000000..b7a751c0276c6306805595edc08bb88e15e17e53
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/property-gcs5.d
@@ -0,0 +1,11 @@
+#name: GNU Property (input without gcs ouput forced with experimental-gcs experimental-gcs-report=none)
+#source: property-gcs.s
+#alltargets: [check_shared_lib_support] *linux*
+#as: -march=armv9.4-a+gcs -defsym __mult__=0
+#ld: -z experimental-gcs -z experimental-gcs-report=none
+#readelf: -n
+
+Displaying notes found in: .note.gnu.property
+[ 	]+Owner[ 	]+Data size[ 	]+Description
+  GNU                  0x00000010	NT_GNU_PROPERTY_TYPE_0
+      Properties: AArch64 feature: GCS
diff --git a/ld/testsuite/ld-aarch64/property-gcs6.d b/ld/testsuite/ld-aarch64/property-gcs6.d
new file mode 100644
index 0000000000000000000000000000000000000000..5abf8126d89e9e2c857f706abd8b9d19717c702a
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/property-gcs6.d
@@ -0,0 +1,12 @@
+#name: GNU Property (input without gcs ouput forced with experimental-gcs experimental-gcs-report=warning)
+#source: property-gcs.s
+#alltargets: [check_shared_lib_support] *linux*
+#as: -march=armv9.4-a+gcs -defsym __mult__=0
+#ld: -z experimental-gcs -z experimental-gcs-report=warning
+#readelf: -n
+#warning: .*property-gcs.*: warning: GCS turned on by -z experimental-gcs on the output when all inputs do not have GCS in NOTE section.
+
+Displaying notes found in: .note.gnu.property
+[ 	]+Owner[ 	]+Data size[ 	]+Description
+  GNU                  0x00000010	NT_GNU_PROPERTY_TYPE_0
+      Properties: AArch64 feature: GCS
diff --git a/ld/testsuite/ld-aarch64/property-gcs7.d b/ld/testsuite/ld-aarch64/property-gcs7.d
new file mode 100644
index 0000000000000000000000000000000000000000..4df5693a27b11544489d934de522bb3c621b3b20
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/property-gcs7.d
@@ -0,0 +1,6 @@
+#name: GNU Property (input without gcs ouput forced with experimental-gcs experimental-gcs-report=error)
+#source: property-gcs.s
+#alltargets: [check_shared_lib_support] *linux*
+#as: -march=armv9.4-a+gcs -defsym __mult__=0
+#ld: -z experimental-gcs -z experimental-gcs-report=error
+#error: .*property-gcs.*: error: GCS turned on by -z experimental-gcs on the output when all inputs do not have GCS in NOTE section.
diff --git a/ld/testsuite/ld-aarch64/property-gcs8.d b/ld/testsuite/ld-aarch64/property-gcs8.d
new file mode 100644
index 0000000000000000000000000000000000000000..463c3ad4197d87f15c724b33b5196911586d2c8f
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/property-gcs8.d
@@ -0,0 +1,11 @@
+#name: GNU Property (input without gcs ouput forced with experimental-gcs=always experimental-gcs-report=none)
+#source: property-gcs.s
+#alltargets: [check_shared_lib_support] *linux*
+#as: -march=armv9.4-a+gcs -defsym __mult__=0
+#ld: -z experimental-gcs=always -z experimental-gcs-report=none
+#readelf: -n
+
+Displaying notes found in: .note.gnu.property
+[ 	]+Owner[ 	]+Data size[ 	]+Description
+  GNU                  0x00000010	NT_GNU_PROPERTY_TYPE_0
+      Properties: AArch64 feature: GCS
diff --git a/ld/testsuite/ld-aarch64/property-gcs9.d b/ld/testsuite/ld-aarch64/property-gcs9.d
new file mode 100644
index 0000000000000000000000000000000000000000..c3083675c8fd5c26db5666f4153b2639737f83f7
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/property-gcs9.d
@@ -0,0 +1,12 @@
+#name: GNU Property (input without gcs ouput forced with experimental-gcs=always experimental-gcs-report=warning)
+#source: property-gcs.s
+#alltargets: [check_shared_lib_support] *linux*
+#as: -march=armv9.4-a+gcs -defsym __mult__=0
+#ld: -z experimental-gcs=always -z experimental-gcs-report=warning
+#readelf: -n
+#warning: .*property-gcs.*: warning: GCS turned on by -z experimental-gcs on the output when all inputs do not have GCS in NOTE section.
+
+Displaying notes found in: .note.gnu.property
+[ 	]+Owner[ 	]+Data size[ 	]+Description
+  GNU                  0x00000010	NT_GNU_PROPERTY_TYPE_0
+      Properties: AArch64 feature: GCS

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

end of thread, other threads:[~2024-01-30  9:14 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-01-04 17:23 [BFD, LD] aarch64: Add support for GCS in AArch64 linker Srinath Parvathaneni
2024-01-05 10:57 ` Nick Clifton
2024-01-30  9:13   ` [Committed][BFD, LD v2] " Srinath Parvathaneni

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).