diff mbox series

[2/3,AARCH64] Add new -mbranch-protection option to combine pointer signing and BTI

Message ID 67f1be3b-0010-880e-4c81-a3781851b94b@arm.com
State New
Headers show
Series [1/3] Add new target hook asm_post_cfi_startproc | expand

Commit Message

Sam Tebbs Nov. 2, 2018, 5:31 p.m. UTC
Hi all,

The -mbranch-protection option combines the functionality of
-msign-return-address and the BTI features new in Armv8.5 to better reflect
their relationship. This new option therefore supersedes and deprecates the
existing -msign-return-address option.

-mbranch-protection=[none|standard|<types>] - Turns on different types of branch
protection available where:

     * "none": Turn of all types of branch protection
     * "standard" : Turns on all the types of protection to their respective
       standard levels.
     * <types> can be "+" separated protection types:

     	* "bti" : Branch Target Identification Mechanism.
	* "pac-ret{+leaf+b-key}": Return Address Signing. The default return
	  address signing is enabled by signing functions that save the return
	  address to memory (non-leaf functions will practically always do this)
	  using the a-key. The optional tuning arguments allow the user to
	  extend the scope of return address signing to include leaf functions
	  and to change the key to b-key. The tuning arguments must proceed the
	  protection type "pac-ret".

Thus -mbranch-protection=standard -> -mbranch-protection=bti+pac-ret.

Its mapping to -msign-return-address is as follows:

     * -mbranch-protection=none -> -msign-return-address=none
     * -mbranch-protection=standard -> -msign-return-address=leaf
     * -mbranch-protection=pac-ret -> -msign-return-address=non-leaf
     * -mbranch-protection=pac-ret+leaf -> -msign-return-address=all

This patch implements the option's skeleton and the "none", "standard" and
"pac-ret" types (along with its "leaf" subtype).

The previous patch in this series is here:
https://gcc.gnu.org/ml/gcc-patches/2018-11/msg00103.html

Bootstrapped successfully and tested on aarch64-none-elf with no regressions.

OK for trunk?

gcc/ChangeLog:

2018-11-02  Sam Tebbs<sam.tebbs@arm.com>

	* config/aarch64/aarch64.c (BRANCH_PROTEC_STR_MAX,
	aarch64_parse_branch_protection,
	struct aarch64_branch_protec_type,
	aarch64_handle_no_branch_protection,
	aarch64_handle_standard_branch_protection,
	aarch64_validate_mbranch_protection,
	aarch64_handle_pac_ret_protection,
	aarch64_handle_attr_branch_protection,
	accepted_branch_protection_string,
	aarch64_pac_ret_subtypes,
	aarch64_branch_protec_types,
	aarch64_handle_pac_ret_leaf): Define.
	(aarch64_override_options_after_change_1): Add check for
	accepted_branch_protection_string.
	(aarch64_override_options): Add check for
	accepted_branch_protection_string.
	(aarch64_option_save): Save accepted_branch_protection_string.
	(aarch64_option_restore): Save
	accepted_branch_protection_string.
	* config/aarch64/aarch64.c (aarch64_attributes): Add branch-protection.
	* config/aarch64/aarch64.opt: Add mbranch-protection. Deprecate
	msign-return-address.
	* doc/invoke.texi: Add mbranch-protection.

gcc/testsuite/ChangeLog:

2018-11-02  Sam Tebbs<sam.tebbs@arm.com>

	* (gcc.target/aarch64/return_address_sign_1.c,
	gcc.target/aarch64/return_address_sign_2.c,
	gcc.target/aarch64/return_address_sign_3.c (__attribute__)): Change
	option to -mbranch-protection.

Comments

Sam Tebbs Nov. 9, 2018, 11:05 a.m. UTC | #1
On 11/02/2018 05:31 PM, Sam Tebbs wrote:

> Hi all,
>
> The -mbranch-protection option combines the functionality of
> -msign-return-address and the BTI features new in Armv8.5 to better reflect
> their relationship. This new option therefore supersedes and deprecates the
> existing -msign-return-address option.
>
> -mbranch-protection=[none|standard|<types>] - Turns on different types of branch
> protection available where:
>
>       * "none": Turn of all types of branch protection
>       * "standard" : Turns on all the types of protection to their respective
>         standard levels.
>       * <types> can be "+" separated protection types:
>
>       	* "bti" : Branch Target Identification Mechanism.
> 	* "pac-ret{+leaf+b-key}": Return Address Signing. The default return
> 	  address signing is enabled by signing functions that save the return
> 	  address to memory (non-leaf functions will practically always do this)
> 	  using the a-key. The optional tuning arguments allow the user to
> 	  extend the scope of return address signing to include leaf functions
> 	  and to change the key to b-key. The tuning arguments must proceed the
> 	  protection type "pac-ret".
>
> Thus -mbranch-protection=standard -> -mbranch-protection=bti+pac-ret.
>
> Its mapping to -msign-return-address is as follows:
>
>       * -mbranch-protection=none -> -msign-return-address=none
>       * -mbranch-protection=standard -> -msign-return-address=leaf
>       * -mbranch-protection=pac-ret -> -msign-return-address=non-leaf
>       * -mbranch-protection=pac-ret+leaf -> -msign-return-address=all
>
> This patch implements the option's skeleton and the "none", "standard" and
> "pac-ret" types (along with its "leaf" subtype).
>
> The previous patch in this series is here:
> https://gcc.gnu.org/ml/gcc-patches/2018-11/msg00103.html
>
> Bootstrapped successfully and tested on aarch64-none-elf with no regressions.
>
> OK for trunk?
>
> gcc/ChangeLog:
>
> 2018-11-02  Sam Tebbs<sam.tebbs@arm.com>
>
> 	* config/aarch64/aarch64.c (BRANCH_PROTEC_STR_MAX,
> 	aarch64_parse_branch_protection,
> 	struct aarch64_branch_protec_type,
> 	aarch64_handle_no_branch_protection,
> 	aarch64_handle_standard_branch_protection,
> 	aarch64_validate_mbranch_protection,
> 	aarch64_handle_pac_ret_protection,
> 	aarch64_handle_attr_branch_protection,
> 	accepted_branch_protection_string,
> 	aarch64_pac_ret_subtypes,
> 	aarch64_branch_protec_types,
> 	aarch64_handle_pac_ret_leaf): Define.
> 	(aarch64_override_options_after_change_1): Add check for
> 	accepted_branch_protection_string.
> 	(aarch64_override_options): Add check for
> 	accepted_branch_protection_string.
> 	(aarch64_option_save): Save accepted_branch_protection_string.
> 	(aarch64_option_restore): Save
> 	accepted_branch_protection_string.
> 	* config/aarch64/aarch64.c (aarch64_attributes): Add branch-protection.
> 	* config/aarch64/aarch64.opt: Add mbranch-protection. Deprecate
> 	msign-return-address.
> 	* doc/invoke.texi: Add mbranch-protection.
>
> gcc/testsuite/ChangeLog:
>
> 2018-11-02  Sam Tebbs<sam.tebbs@arm.com>
>
> 	* (gcc.target/aarch64/return_address_sign_1.c,
> 	gcc.target/aarch64/return_address_sign_2.c,
> 	gcc.target/aarch64/return_address_sign_3.c (__attribute__)): Change
> 	option to -mbranch-protection.
>

ping
Sudakshina Das Nov. 12, 2018, 6:24 p.m. UTC | #2
Hi Sam

On 02/11/18 17:31, Sam Tebbs wrote:
> Hi all,
> 
> The -mbranch-protection option combines the functionality of
> -msign-return-address and the BTI features new in Armv8.5 to better reflect
> their relationship. This new option therefore supersedes and deprecates the
> existing -msign-return-address option.
> 
> -mbranch-protection=[none|standard|<types>] - Turns on different types of branch
> protection available where:
> 
>       * "none": Turn of all types of branch protection
>       * "standard" : Turns on all the types of protection to their respective
>         standard levels.
>       * <types> can be "+" separated protection types:
> 
>       	* "bti" : Branch Target Identification Mechanism.
> 	* "pac-ret{+leaf+b-key}": Return Address Signing. The default return
> 	  address signing is enabled by signing functions that save the return
> 	  address to memory (non-leaf functions will practically always do this)
> 	  using the a-key. The optional tuning arguments allow the user to
> 	  extend the scope of return address signing to include leaf functions
> 	  and to change the key to b-key. The tuning arguments must proceed the
> 	  protection type "pac-ret".
> 
> Thus -mbranch-protection=standard -> -mbranch-protection=bti+pac-ret.
> 
> Its mapping to -msign-return-address is as follows:
> 
>       * -mbranch-protection=none -> -msign-return-address=none
>       * -mbranch-protection=standard -> -msign-return-address=leaf
>       * -mbranch-protection=pac-ret -> -msign-return-address=non-leaf
>       * -mbranch-protection=pac-ret+leaf -> -msign-return-address=all
> 
> This patch implements the option's skeleton and the "none", "standard" and
> "pac-ret" types (along with its "leaf" subtype).
> 
> The previous patch in this series is here:
> https://gcc.gnu.org/ml/gcc-patches/2018-11/msg00103.html
> 
> Bootstrapped successfully and tested on aarch64-none-elf with no regressions.
> 
> OK for trunk?
> 

Thank for doing this. I am not a maintainer so you will need a
maintainer's approval. Only nit, that I would add is that it would
be good to have more test coverage, specially for the new parsing
functions that have been added and the errors that are added.

Example checking a few valid and invalid combinations of the options
like:
-mbranch-protection=pac-ret -mbranch-protection=none //disables
everything
-mbranch-protection=leaf  //errors out
-mbranch-protection=none+pac-ret //errors out
... etc

Also instead of removing all the old deprecated options, you can keep
one (or a copy of one) to check for the deprecated warning.


diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 
e290128f535f3e6b515bff5a81fae0aa0d1c8baf..07cfe69dc3dd9161a2dd93089ccf52ef251208d2 
100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -15221,13 +15222,18 @@ accessed using a single instruction and 
emitted after each function.  This
  limits the maximum size of functions to 1MB.  This is enabled by 
default for
  @option{-mcmodel=tiny}.

-@item -msign-return-address=@var{scope}
-@opindex msign-return-address
-Select the function scope on which return address signing will be applied.
-Permissible values are @samp{none}, which disables return address signing,
-@samp{non-leaf}, which enables pointer signing for functions which are 
not leaf
-functions, and @samp{all}, which enables pointer signing for all 
functions.  The
-default value is @samp{none}.
+@item 
-mbranch-protection=@var{none}|@var{standard}|@var{pac-ret}[+@var{leaf}]
+@opindex mbranch-protection
+Select the branch protection features to use.
+@samp{none} is the default and turns off all types of branch protection.
+@samp{standard} turns on all types of branch protection features.  If a 
feature
+has additional tuning options, then @samp{standard} sets it to its standard
+level.
+@samp{pac-ret[+@var{leaf}]} turns on return address signing to its standard
+level: signing functions that save the return address to memory (non-leaf
+functions will practically always do this) using the a-key.  The optional
+argument @samp{leaf} can be used to extend the signing to include leaf
+functions.

I am not sure if deleting the previous documentation of
-msign-retun-address is the way to go. Maybe add a "this has been
deprecated and refer to -mbranch-protection" to its description.

Thanks
Sudi

> gcc/ChangeLog:
> 
> 2018-11-02  Sam Tebbs<sam.tebbs@arm.com>
> 
> 	* config/aarch64/aarch64.c (BRANCH_PROTEC_STR_MAX,
> 	aarch64_parse_branch_protection,
> 	struct aarch64_branch_protec_type,
> 	aarch64_handle_no_branch_protection,
> 	aarch64_handle_standard_branch_protection,
> 	aarch64_validate_mbranch_protection,
> 	aarch64_handle_pac_ret_protection,
> 	aarch64_handle_attr_branch_protection,
> 	accepted_branch_protection_string,
> 	aarch64_pac_ret_subtypes,
> 	aarch64_branch_protec_types,
> 	aarch64_handle_pac_ret_leaf): Define.
> 	(aarch64_override_options_after_change_1): Add check for
> 	accepted_branch_protection_string.
> 	(aarch64_override_options): Add check for
> 	accepted_branch_protection_string.
> 	(aarch64_option_save): Save accepted_branch_protection_string.
> 	(aarch64_option_restore): Save
> 	accepted_branch_protection_string.
> 	* config/aarch64/aarch64.c (aarch64_attributes): Add branch-protection.
> 	* config/aarch64/aarch64.opt: Add mbranch-protection. Deprecate
> 	msign-return-address.
> 	* doc/invoke.texi: Add mbranch-protection.
> 
> gcc/testsuite/ChangeLog:
> 
> 2018-11-02  Sam Tebbs<sam.tebbs@arm.com>
> 
> 	* (gcc.target/aarch64/return_address_sign_1.c,
> 	gcc.target/aarch64/return_address_sign_2.c,
> 	gcc.target/aarch64/return_address_sign_3.c (__attribute__)): Change
> 	option to -mbranch-protection.
>
Sam Tebbs Nov. 22, 2018, 4:54 p.m. UTC | #3
On 11/12/18 6:24 PM, Sudakshina Das wrote:
> Hi Sam
>
> On 02/11/18 17:31, Sam Tebbs wrote:
>> Hi all,
>>
>> The -mbranch-protection option combines the functionality of
>> -msign-return-address and the BTI features new in Armv8.5 to better reflect
>> their relationship. This new option therefore supersedes and deprecates the
>> existing -msign-return-address option.
>>
>> -mbranch-protection=[none|standard|<types>] - Turns on different types of branch
>> protection available where:
>>
>>        * "none": Turn of all types of branch protection
>>        * "standard" : Turns on all the types of protection to their respective
>>          standard levels.
>>        * <types> can be "+" separated protection types:
>>
>>        	* "bti" : Branch Target Identification Mechanism.
>> 	* "pac-ret{+leaf+b-key}": Return Address Signing. The default return
>> 	  address signing is enabled by signing functions that save the return
>> 	  address to memory (non-leaf functions will practically always do this)
>> 	  using the a-key. The optional tuning arguments allow the user to
>> 	  extend the scope of return address signing to include leaf functions
>> 	  and to change the key to b-key. The tuning arguments must proceed the
>> 	  protection type "pac-ret".
>>
>> Thus -mbranch-protection=standard -> -mbranch-protection=bti+pac-ret.
>>
>> Its mapping to -msign-return-address is as follows:
>>
>>        * -mbranch-protection=none -> -msign-return-address=none
>>        * -mbranch-protection=standard -> -msign-return-address=leaf
>>        * -mbranch-protection=pac-ret -> -msign-return-address=non-leaf
>>        * -mbranch-protection=pac-ret+leaf -> -msign-return-address=all
>>
>> This patch implements the option's skeleton and the "none", "standard" and
>> "pac-ret" types (along with its "leaf" subtype).
>>
>> The previous patch in this series is here:
>> https://gcc.gnu.org/ml/gcc-patches/2018-11/msg00103.html
>>
>> Bootstrapped successfully and tested on aarch64-none-elf with no regressions.
>>
>> OK for trunk?
>>
> Thank for doing this. I am not a maintainer so you will need a
> maintainer's approval. Only nit, that I would add is that it would
> be good to have more test coverage, specially for the new parsing
> functions that have been added and the errors that are added.
>
> Example checking a few valid and invalid combinations of the options
> like:
> -mbranch-protection=pac-ret -mbranch-protection=none //disables
> everything
> -mbranch-protection=leaf  //errors out
> -mbranch-protection=none+pac-ret //errors out
> ... etc
> Also instead of removing all the old deprecated options, you can keep
> one (or a copy of one) to check for the deprecated warning.

Hi Sudi,

Thanks for the feedback, I've incorporated your suggestions into the 
attached patch and the updated changelog.

gcc/ChangeLog:

2018-11-22  Sam Tebbs<sam.tebbs@arm.com>

	* config/aarch64/aarch64.c (BRANCH_PROTEC_STR_MAX,
	aarch64_parse_branch_protection,
	struct aarch64_branch_protec_type,
	aarch64_handle_no_branch_protection,
	aarch64_handle_standard_branch_protection,
	aarch64_validate_mbranch_protection,
	aarch64_handle_pac_ret_protection,
	aarch64_handle_attr_branch_protection,
	accepted_branch_protection_string,
	aarch64_pac_ret_subtypes,
	aarch64_branch_protec_types,
	aarch64_handle_pac_ret_leaf): Define.
	(aarch64_override_options_after_change_1): Add check for
	accepted_branch_protection_string.
	(aarch64_override_options): Add check for
	accepted_branch_protection_string.
	(aarch64_option_save): Save accepted_branch_protection_string.
	(aarch64_option_restore): Save
	accepted_branch_protection_string.
	* config/aarch64/aarch64.c (aarch64_attributes): Add branch-protection.
	* config/aarch64/aarch64.opt: Add mbranch-protection. Deprecate
	msign-return-address.
	* doc/invoke.texi: Add mbranch-protection.

gcc/testsuite/ChangeLog:

2018-11-22  Sam Tebbs<sam.tebbs@arm.com>

	* (gcc.target/aarch64/return_address_sign_1.c,
	gcc.target/aarch64/return_address_sign_2.c,
	gcc.target/aarch64/return_address_sign_3.c (__attribute__)): Change
	option to -mbranch-protection.
	* gcc.target/aarch64/(branch-protection-option.c,
	branch-protection-option-2.c, branch-protection-attr.c,
	branch-protection-attr-2.c): New file.
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 0d89ba27e4a7a02903d6cb3de6c19b097cb84d16..c938cdf93f255949969a7fe7a4f8a2c18bfa6115 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -183,6 +183,12 @@ bool aarch64_pcrelative_literal_loads;
 /* Global flag for whether frame pointer is enabled.  */
 bool aarch64_use_frame_pointer;
 
+#define BRANCH_PROTEC_STR_MAX 255
+char *accepted_branch_protection_string = NULL;
+
+static enum aarch64_parse_opt_result
+aarch64_parse_branch_protection (const char*, char**);
+
 /* Support for command line parsing of boolean flags in the tuning
    structures.  */
 struct aarch64_flag_desc
@@ -1108,6 +1114,80 @@ aarch64_cc;
 
 #define AARCH64_INVERSE_CONDITION_CODE(X) ((aarch64_cc) (((int) X) ^ 1))
 
+struct aarch64_branch_protec_type
+{
+  /* The type's name that the user passes to the branch-protection option
+    string.  */
+  const char* name;
+  /* Function to handle the protection type and set global variables.
+    First argument is the string token corresponding with this type and the
+    second argument is the next token in the option string.
+    Return values:
+    * AARCH64_PARSE_OK: Handling was sucessful.
+    * AARCH64_INVALID_ARG: The type is invalid in this context and the caller
+      should print an error.
+    * AARCH64_INVALID_FEATURE: The type is invalid and the handler prints its
+      own error.  */
+  enum aarch64_parse_opt_result (*handler)(char*, char*);
+  /* A list of types that can follow this type in the option string.  */
+  const aarch64_branch_protec_type* subtypes;
+  unsigned int num_subtypes;
+};
+
+static enum aarch64_parse_opt_result
+aarch64_handle_no_branch_protection (char* str ATTRIBUTE_UNUSED, char* rest)
+{
+  aarch64_ra_sign_scope = AARCH64_FUNCTION_NONE;
+  if (rest)
+    {
+      error ("unexpected %<%s%> after %<%s%>", rest, str);
+      return AARCH64_PARSE_INVALID_FEATURE;
+    }
+  return AARCH64_PARSE_OK;
+}
+
+static enum aarch64_parse_opt_result
+aarch64_handle_standard_branch_protection (char* str ATTRIBUTE_UNUSED,
+					    char* rest ATTRIBUTE_UNUSED)
+{
+  aarch64_ra_sign_scope = AARCH64_FUNCTION_NON_LEAF;
+  if (rest)
+    {
+      error ("unexpected %<%s%> after %<%s%>", rest, str);
+      return AARCH64_PARSE_INVALID_FEATURE;
+    }
+  return AARCH64_PARSE_OK;
+}
+
+static enum aarch64_parse_opt_result
+aarch64_handle_pac_ret_protection (char* str ATTRIBUTE_UNUSED,
+				    char* rest ATTRIBUTE_UNUSED)
+{
+  aarch64_ra_sign_scope = AARCH64_FUNCTION_NON_LEAF;
+  return AARCH64_PARSE_OK;
+}
+
+static enum aarch64_parse_opt_result
+aarch64_handle_pac_ret_leaf (char* str ATTRIBUTE_UNUSED,
+			      char* rest ATTRIBUTE_UNUSED)
+{
+  aarch64_ra_sign_scope = AARCH64_FUNCTION_ALL;
+  return AARCH64_PARSE_OK;
+}
+
+static const struct aarch64_branch_protec_type aarch64_pac_ret_subtypes[] = {
+  { "leaf", aarch64_handle_pac_ret_leaf, NULL, 0 },
+  { NULL, NULL, NULL, 0 }
+};
+
+static const struct aarch64_branch_protec_type aarch64_branch_protec_types[] = {
+  { "none", aarch64_handle_no_branch_protection, NULL, 0 },
+  { "standard", aarch64_handle_standard_branch_protection, NULL, 0 },
+  { "pac-ret", aarch64_handle_pac_ret_protection, aarch64_pac_ret_subtypes,
+    sizeof (aarch64_pac_ret_subtypes) / sizeof (aarch64_branch_protec_type) },
+  { NULL, NULL, NULL, 0 }
+};
+
 /* The condition codes of the processor, and the inverse function.  */
 static const char * const aarch64_condition_codes[] =
 {
@@ -10886,6 +10966,12 @@ aarch64_parse_override_string (const char* input_string,
 static void
 aarch64_override_options_after_change_1 (struct gcc_options *opts)
 {
+  if (accepted_branch_protection_string)
+    {
+      opts->x_aarch64_branch_protection_string
+	= xstrdup (accepted_branch_protection_string);
+    }
+
   /* PR 70044: We have to be careful about being called multiple times for the
      same function.  This means all changes should be repeatable.  */
 
@@ -11171,6 +11257,110 @@ aarch64_validate_mcpu (const char *str, const struct processor **res,
   return false;
 }
 
+/* Parses CONST_STR for branch protection features specified in
+   aarch64_branch_protec_types, and set any global variables required.  Returns
+   the parsing result and assigns LAST_STR to the last processed token from
+   CONST_STR so that it can be used for error reporting.  */
+
+static enum
+aarch64_parse_opt_result aarch64_parse_branch_protection (const char *const_str,
+							  char** last_str)
+{
+  char *str_root = xstrdup (const_str);
+  char* token_save = NULL;
+  char *str = strtok_r (str_root, "+", &token_save);
+  enum aarch64_parse_opt_result res = AARCH64_PARSE_OK;
+  if (!str)
+    res = AARCH64_PARSE_MISSING_ARG;
+  else
+    {
+      char *next_str = strtok_r (NULL, "+", &token_save);
+      /* Reset the branch protection features to their defaults.  */
+      aarch64_handle_no_branch_protection (NULL, NULL);
+
+      while (str && res == AARCH64_PARSE_OK)
+	{
+	  const aarch64_branch_protec_type* type = aarch64_branch_protec_types;
+	  bool found = false;
+	  /* Search for this type.  */
+	  while (type && type->name && !found && res == AARCH64_PARSE_OK)
+	    {
+	      if (strcmp (str, type->name) == 0)
+		{
+		  found = true;
+		  res = type->handler (str, next_str);
+		  str = next_str;
+		  next_str = strtok_r (NULL, "+", &token_save);
+		}
+	      else
+		type++;
+	    }
+	  if (found && res == AARCH64_PARSE_OK)
+	    {
+	      bool found_subtype = true;
+	      /* Loop through each token until we find one that isn't a
+		 subtype.  */
+	      while (found_subtype)
+		{
+		  found_subtype = false;
+		  const aarch64_branch_protec_type *subtype = type->subtypes;
+		  /* Search for the subtype.  */
+		  while (str && subtype && subtype->name && !found_subtype
+			  && res == AARCH64_PARSE_OK)
+		    {
+		      if (strcmp (str, subtype->name) == 0)
+			{
+			  found_subtype = true;
+			  res = subtype->handler (str, next_str);
+			  str = next_str;
+			  next_str = strtok_r (NULL, "+", &token_save);
+			}
+		      else
+			subtype++;
+		    }
+		}
+	    }
+	  else if (!found)
+	    res = AARCH64_PARSE_INVALID_ARG;
+	}
+    }
+  /* Copy the last processed token into the argument to pass it back.
+    Used by option and attribute validation to print the offending token.  */
+  if (last_str)
+    {
+      if (str) strcpy (*last_str, str);
+      else *last_str = NULL;
+    }
+  if (res == AARCH64_PARSE_OK)
+    {
+      /* If needed, alloc the accepted string then copy in const_str.
+	Used by override_option_after_change_1.  */
+      if (!accepted_branch_protection_string)
+	accepted_branch_protection_string = (char *) xmalloc (
+						      BRANCH_PROTEC_STR_MAX
+							+ 1);
+      strncpy (accepted_branch_protection_string, const_str,
+		BRANCH_PROTEC_STR_MAX + 1);
+      /* Forcibly null-terminate.  */
+      accepted_branch_protection_string[BRANCH_PROTEC_STR_MAX] = '\0';
+    }
+  return res;
+}
+
+static bool
+aarch64_validate_mbranch_protection (const char *const_str)
+{
+  char *str = (char *) xmalloc (strlen (const_str));
+  enum aarch64_parse_opt_result res =
+    aarch64_parse_branch_protection (const_str, &str);
+  if (res == AARCH64_PARSE_INVALID_ARG)
+    error ("invalid arg %<%s%> for %<-mbranch-protection=%>", str);
+  else if (res == AARCH64_PARSE_MISSING_ARG)
+    error ("missing arg for %<-mbranch-protection=%>");
+  free (str);
+  return res == AARCH64_PARSE_OK;
+}
+
 /* Validate a command-line -march option.  Parse the arch and extensions
    (if any) specified in STR and throw errors if appropriate.  Put the
    results, if they are valid, in RES and ISA_FLAGS.  Return whether the
@@ -11305,6 +11495,9 @@ aarch64_override_options (void)
   selected_arch = NULL;
   selected_tune = NULL;
 
+  if (aarch64_branch_protection_string)
+    aarch64_validate_mbranch_protection (aarch64_branch_protection_string);
+
   /* -mcpu=CPU is shorthand for -march=ARCH_FOR_CPU, -mtune=CPU.
      If either of -march or -mtune is given, they override their
      respective component of -mcpu.  */
@@ -11473,6 +11666,8 @@ static void
 aarch64_option_save (struct cl_target_option *ptr, struct gcc_options *opts)
 {
   ptr->x_aarch64_override_tune_string = opts->x_aarch64_override_tune_string;
+  ptr->x_aarch64_branch_protection_string
+    = opts->x_aarch64_branch_protection_string;
 }
 
 /* Implements TARGET_OPTION_RESTORE.  Restore the backend codegen decisions
@@ -11486,6 +11681,13 @@ aarch64_option_restore (struct gcc_options *opts, struct cl_target_option *ptr)
   opts->x_explicit_arch = ptr->x_explicit_arch;
   selected_arch = aarch64_get_arch (ptr->x_explicit_arch);
   opts->x_aarch64_override_tune_string = ptr->x_aarch64_override_tune_string;
+  opts->x_aarch64_branch_protection_string
+    = ptr->x_aarch64_branch_protection_string;
+  if (opts->x_aarch64_branch_protection_string)
+    {
+      aarch64_parse_branch_protection (opts->x_aarch64_branch_protection_string,
+					NULL);
+    }
 
   aarch64_override_options_internal (opts);
 }
@@ -11680,6 +11882,37 @@ aarch64_handle_attr_cpu (const char *str)
   return false;
 }
 
+/* Handle the argument STR to the branch-protection= attribute.  */
+
+ static bool
+ aarch64_handle_attr_branch_protection (const char* str)
+ {
+  char *err_str = (char *) xmalloc (strlen (str));
+  enum aarch64_parse_opt_result res = aarch64_parse_branch_protection (str,
+								      &err_str);
+  bool success = false;
+  switch (res)
+    {
+     case AARCH64_PARSE_MISSING_ARG:
+       error ("missing argument to %<target(\"branch-protection=\")%> pragma or"
+	      " attribute");
+       break;
+     case AARCH64_PARSE_INVALID_ARG:
+       error ("invalid protection type (\"%s\") in %<target(\"branch-protection"
+	      "=\")%> pragma or attribute", err_str);
+       break;
+     case AARCH64_PARSE_OK:
+       success = true;
+      /* Fall through.  */
+     case AARCH64_PARSE_INVALID_FEATURE:
+       break;
+     default:
+       gcc_unreachable ();
+    }
+  free (err_str);
+  return success;
+ }
+
 /* Handle the argument STR to the tune= target attribute.  */
 
 static bool
@@ -11778,6 +12011,8 @@ static const struct aarch64_attribute_info aarch64_attributes[] =
   { "cpu", aarch64_attr_custom, false, aarch64_handle_attr_cpu, OPT_mcpu_ },
   { "tune", aarch64_attr_custom, false, aarch64_handle_attr_tune,
      OPT_mtune_ },
+  { "branch-protection", aarch64_attr_custom, false,
+     aarch64_handle_attr_branch_protection, OPT_mbranch_protection_ },
   { "sign-return-address", aarch64_attr_enum, false, NULL,
      OPT_msign_return_address_ },
   { NULL, aarch64_attr_custom, false, NULL, OPT____ }
diff --git a/gcc/config/aarch64/aarch64.opt b/gcc/config/aarch64/aarch64.opt
index b2e80cbf6f1f9727c4309874b1122f975fb6b9be..9460636d93b67af1525f028176aa78e6fed4e45f 100644
--- a/gcc/config/aarch64/aarch64.opt
+++ b/gcc/config/aarch64/aarch64.opt
@@ -149,8 +149,12 @@ mpc-relative-literal-loads
 Target Report Save Var(pcrelative_literal_loads) Init(2) Save
 PC relative literal loads.
 
+mbranch-protection=
+Target RejectNegative Joined Var(aarch64_branch_protection_string) Save
+Use branch-protection features.
+
 msign-return-address=
-Target RejectNegative Report Joined Enum(aarch64_ra_sign_scope_t) Var(aarch64_ra_sign_scope) Init(AARCH64_FUNCTION_NONE) Save
+Target Deprecated RejectNegative Joined Enum(aarch64_ra_sign_scope_t) Var(aarch64_ra_sign_scope) Init(AARCH64_FUNCTION_NONE) Save
 Select return address signing scope.
 
 Enum
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index d46ebd02c4e0fee7b1c93a9e96d80113f6af93a7..6a822c91f04cbc464b6efe3639106243e3deae02 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -628,6 +628,7 @@ Objective-C and Objective-C++ Dialects}.
 -mlow-precision-recip-sqrt  -mlow-precision-sqrt  -mlow-precision-div @gol
 -mpc-relative-literal-loads @gol
 -msign-return-address=@var{scope} @gol
+-mbranch-protection=@var{none}|@var{standard}|@var{pac-ret}[+@var{leaf}] @gol
 -march=@var{name}  -mcpu=@var{name}  -mtune=@var{name}  @gol
 -moverride=@var{string}  -mverbose-cost-dump  -mtrack-speculation} 
 
@@ -15637,7 +15638,21 @@ Select the function scope on which return address signing will be applied.
 Permissible values are @samp{none}, which disables return address signing,
 @samp{non-leaf}, which enables pointer signing for functions which are not leaf
 functions, and @samp{all}, which enables pointer signing for all functions.  The
-default value is @samp{none}.
+default value is @samp{none}. This option has been deprecated by
+-mbranch-protection.
+
+@item -mbranch-protection=@var{none}|@var{standard}|@var{pac-ret}[+@var{leaf}]
+@opindex mbranch-protection
+Select the branch protection features to use.
+@samp{none} is the default and turns off all types of branch protection.
+@samp{standard} turns on all types of branch protection features.  If a feature
+has additional tuning options, then @samp{standard} sets it to its standard
+level.
+@samp{pac-ret[+@var{leaf}]} turns on return address signing to its standard
+level: signing functions that save the return address to memory (non-leaf
+functions will practically always do this) using the a-key.  The optional
+argument @samp{leaf} can be used to extend the signing to include leaf
+functions.
 
 @item -msve-vector-bits=@var{bits}
 @opindex msve-vector-bits
diff --git a/gcc/testsuite/gcc.target/aarch64/branch-protection-attr-2.c b/gcc/testsuite/gcc.target/aarch64/branch-protection-attr-2.c
new file mode 100644
index 0000000000000000000000000000000000000000..19b3511ab6111a895383f5ddf93644110c3971c6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/branch-protection-attr-2.c
@@ -0,0 +1,16 @@
+/* { dg-do "compile" } */
+
+void __attribute__ ((target("branch-protection=pac-ret+leaf,branch-protection=none")))
+foo ()
+{
+}
+
+void __attribute__ ((target("branch-protection=pac-ret,branch-protection=none")))
+foo2 ()
+{
+  /* Function call here to make this a non-leaf function, so that it is covered by pac-ret.  */
+  foo ();
+}
+
+/* { dg-final { scan-assembler-not "\tautiasp\t" } } */
+/* { dg-final { scan-assembler-not "\tpaciasp\t" } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/branch-protection-attr.c b/gcc/testsuite/gcc.target/aarch64/branch-protection-attr.c
new file mode 100644
index 0000000000000000000000000000000000000000..229ce1ca7bebce060204946682af175389527193
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/branch-protection-attr.c
@@ -0,0 +1,22 @@
+/* { dg-do "compile" } */
+
+void __attribute__ ((target("branch-protection=leaf")))
+foo1 ()
+{
+}
+/* { dg-error {invalid protection type \("leaf"\) in 'target\("branch-protection="\)' pragma or attribute} "" { target *-*-* } 5 } */
+/* { dg-error {pragma or attribute 'target\("branch-protection=leaf"\)' is not valid} "" { target *-*-* } 5 } */
+
+void __attribute__ ((target("branch-protection=none+pac-ret")))
+foo2 ()
+{
+}
+/* { dg-error "unexpected 'pac-ret' after 'none'" "" { target *-*-* } 12 } */
+/* { dg-error {pragma or attribute 'target\("branch-protection=none\+pac-ret"\)' is not valid} "" { target *-*-* } 12 } */
+
+void __attribute__ ((target("branch-protection=")))
+foo3 ()
+{
+}
+/* { dg-error {missing argument to 'target\("branch-protection="\)' pragma or attribute} "" { target *-*-* } 19 } */
+/* { dg-error {pragma or attribute 'target\("branch-protection="\)' is not valid} "" { target *-*-* } 19 } */
diff --git a/gcc/testsuite/gcc.target/aarch64/branch-protection-option-2.c b/gcc/testsuite/gcc.target/aarch64/branch-protection-option-2.c
new file mode 100644
index 0000000000000000000000000000000000000000..281851136520ece286186fd18c1a64b984f0b3e8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/branch-protection-option-2.c
@@ -0,0 +1,9 @@
+/* { dg-do "compile" } */
+/* { dg-options "-mbranch-protection=pac-ret+leaf -mbranch-protection=none" } */
+
+void foo2 ()
+{
+}
+
+/* { dg-final { scan-assembler-not "\tautiasp\t" } } */
+/* { dg-final { scan-assembler-not "\tpaciasp\t" } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/branch-protection-option.c b/gcc/testsuite/gcc.target/aarch64/branch-protection-option.c
new file mode 100644
index 0000000000000000000000000000000000000000..1b3bf4ee2b88a6e89d78f99766889904849a89db
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/branch-protection-option.c
@@ -0,0 +1,4 @@
+/* { dg-do "compile" } */
+/* { dg-options "-mbranch-protection=leaf -mbranch-protection=none+pac-ret" } */
+
+/* { dg-error "unexpected 'pac-ret' after 'none'"  "" { target *-*-* } 0 } */
diff --git a/gcc/testsuite/gcc.target/aarch64/return_address_sign_1.c b/gcc/testsuite/gcc.target/aarch64/return_address_sign_1.c
index f87c3d28d1edff473a787a39a436e57076f97508..0140bee194f5a3ec53e794984c2f9b0e96bdbb63 100644
--- a/gcc/testsuite/gcc.target/aarch64/return_address_sign_1.c
+++ b/gcc/testsuite/gcc.target/aarch64/return_address_sign_1.c
@@ -1,6 +1,6 @@
 /* Testing return address signing where no combined instructions used.  */
 /* { dg-do compile } */
-/* { dg-options "-O2 -msign-return-address=all" } */
+/* { dg-options "-O2 -mbranch-protection=pac-ret+leaf" } */
 /* { dg-require-effective-target lp64 } */
 
 int foo (int);
diff --git a/gcc/testsuite/gcc.target/aarch64/return_address_sign_2.c b/gcc/testsuite/gcc.target/aarch64/return_address_sign_2.c
index c5c1439b92e6637f85c47c6161cd797c0d68df25..a4bc5b4533382d3d21085a763028576f72531ed7 100644
--- a/gcc/testsuite/gcc.target/aarch64/return_address_sign_2.c
+++ b/gcc/testsuite/gcc.target/aarch64/return_address_sign_2.c
@@ -1,6 +1,6 @@
 /* Testing return address signing where combined instructions used.  */
 /* { dg-do compile } */
-/* { dg-options "-O2 -msign-return-address=all" } */
+/* { dg-options "-O2 -mbranch-protection=pac-ret+leaf" } */
 /* { dg-require-effective-target lp64 } */
 
 int foo (int);
diff --git a/gcc/testsuite/gcc.target/aarch64/return_address_sign_3.c b/gcc/testsuite/gcc.target/aarch64/return_address_sign_3.c
index 7d9ec6eebd1ce452013d2895a551671c59e98f0c..e39ed34ab1c13d1368f4a625b4a466eb76354ef8 100644
--- a/gcc/testsuite/gcc.target/aarch64/return_address_sign_3.c
+++ b/gcc/testsuite/gcc.target/aarch64/return_address_sign_3.c
@@ -1,17 +1,17 @@
 /* Testing the disable of return address signing.  */
 /* { dg-do compile } */
-/* { dg-options "-O2 -msign-return-address=all" } */
+/* { dg-options "-O2 -mbranch-protection=pac-ret+leaf" } */
 /* { dg-require-effective-target lp64 } */
 
 int bar (int, int);
 
-int __attribute__ ((target ("arch=armv8.3-a, sign-return-address=non-leaf")))
+int __attribute__ ((target ("arch=armv8.3-a, branch-protection=pac-ret")))
 func1_leaf (int a, int b, int c, int d)
 {
   return a + b + c + d;
 }
 
-int __attribute__ ((target ("arch=armv8.3-a, sign-return-address=none")))
+int __attribute__ ((target ("arch=armv8.3-a, branch-protection=none")))
 func2_none (int a, int b, int c, int d)
 {
   return c + bar (a, b) + d;
Sam Tebbs Dec. 20, 2018, 4:38 p.m. UTC | #4
On 11/22/18 4:54 PM, Sam Tebbs wrote:
> On 11/12/18 6:24 PM, Sudakshina Das wrote:
>> Hi Sam
>>
>> On 02/11/18 17:31, Sam Tebbs wrote:
>>> Hi all,
>>>
>>> The -mbranch-protection option combines the functionality of
>>> -msign-return-address and the BTI features new in Armv8.5 to better reflect
>>> their relationship. This new option therefore supersedes and deprecates the
>>> existing -msign-return-address option.
>>>
>>> -mbranch-protection=[none|standard|<types>] - Turns on different types of branch
>>> protection available where:
>>>
>>>         * "none": Turn of all types of branch protection
>>>         * "standard" : Turns on all the types of protection to their respective
>>>           standard levels.
>>>         * <types> can be "+" separated protection types:
>>>
>>>         	* "bti" : Branch Target Identification Mechanism.
>>> 	* "pac-ret{+leaf+b-key}": Return Address Signing. The default return
>>> 	  address signing is enabled by signing functions that save the return
>>> 	  address to memory (non-leaf functions will practically always do this)
>>> 	  using the a-key. The optional tuning arguments allow the user to
>>> 	  extend the scope of return address signing to include leaf functions
>>> 	  and to change the key to b-key. The tuning arguments must proceed the
>>> 	  protection type "pac-ret".
>>>
>>> Thus -mbranch-protection=standard -> -mbranch-protection=bti+pac-ret.
>>>
>>> Its mapping to -msign-return-address is as follows:
>>>
>>>         * -mbranch-protection=none -> -msign-return-address=none
>>>         * -mbranch-protection=standard -> -msign-return-address=leaf
>>>         * -mbranch-protection=pac-ret -> -msign-return-address=non-leaf
>>>         * -mbranch-protection=pac-ret+leaf -> -msign-return-address=all
>>>
>>> This patch implements the option's skeleton and the "none", "standard" and
>>> "pac-ret" types (along with its "leaf" subtype).
>>>
>>> The previous patch in this series is here:
>>> https://gcc.gnu.org/ml/gcc-patches/2018-11/msg00103.html
>>>
>>> Bootstrapped successfully and tested on aarch64-none-elf with no regressions.
>>>
>>> OK for trunk?
>>>
>> Thank for doing this. I am not a maintainer so you will need a
>> maintainer's approval. Only nit, that I would add is that it would
>> be good to have more test coverage, specially for the new parsing
>> functions that have been added and the errors that are added.
>>
>> Example checking a few valid and invalid combinations of the options
>> like:
>> -mbranch-protection=pac-ret -mbranch-protection=none //disables
>> everything
>> -mbranch-protection=leaf  //errors out
>> -mbranch-protection=none+pac-ret //errors out
>> ... etc
>> Also instead of removing all the old deprecated options, you can keep
>> one (or a copy of one) to check for the deprecated warning.
> Hi Sudi,
>
> Thanks for the feedback, I've incorporated your suggestions into the
> attached patch and the updated changelog.
>
> gcc/ChangeLog:
>
> 2018-11-22  Sam Tebbs<sam.tebbs@arm.com>
>
> 	* config/aarch64/aarch64.c (BRANCH_PROTEC_STR_MAX,
> 	aarch64_parse_branch_protection,
> 	struct aarch64_branch_protec_type,
> 	aarch64_handle_no_branch_protection,
> 	aarch64_handle_standard_branch_protection,
> 	aarch64_validate_mbranch_protection,
> 	aarch64_handle_pac_ret_protection,
> 	aarch64_handle_attr_branch_protection,
> 	accepted_branch_protection_string,
> 	aarch64_pac_ret_subtypes,
> 	aarch64_branch_protec_types,
> 	aarch64_handle_pac_ret_leaf): Define.
> 	(aarch64_override_options_after_change_1): Add check for
> 	accepted_branch_protection_string.
> 	(aarch64_override_options): Add check for
> 	accepted_branch_protection_string.
> 	(aarch64_option_save): Save accepted_branch_protection_string.
> 	(aarch64_option_restore): Save
> 	accepted_branch_protection_string.
> 	* config/aarch64/aarch64.c (aarch64_attributes): Add branch-protection.
> 	* config/aarch64/aarch64.opt: Add mbranch-protection. Deprecate
> 	msign-return-address.
> 	* doc/invoke.texi: Add mbranch-protection.
>
> gcc/testsuite/ChangeLog:
>
> 2018-11-22  Sam Tebbs<sam.tebbs@arm.com>
>
> 	* (gcc.target/aarch64/return_address_sign_1.c,
> 	gcc.target/aarch64/return_address_sign_2.c,
> 	gcc.target/aarch64/return_address_sign_3.c (__attribute__)): Change
> 	option to -mbranch-protection.
> 	* gcc.target/aarch64/(branch-protection-option.c,
> 	branch-protection-option-2.c, branch-protection-attr.c,
> 	branch-protection-attr-2.c): New file.

Hi all,

Attached is an updated patch with branch_protec_type renamed to 
branch_protect_type, some unneeded ATTRIBUTE_USED removed and an added 
use of ARRAY_SIZE.

Below is the updated changelog.

OK for trunk? I have committed the preceding patch in the series.

gcc/ChangeLog:

2018-12-20  Sam Tebbs<sam.tebbs@arm.com>

	* config/aarch64/aarch64.c (BRANCH_PROTECT_STR_MAX,
	aarch64_parse_branch_protection,
	struct aarch64_branch_protect_type,
	aarch64_handle_no_branch_protection,
	aarch64_handle_standard_branch_protection,
	aarch64_validate_mbranch_protection,
	aarch64_handle_pac_ret_protection,
	aarch64_handle_attr_branch_protection,
	accepted_branch_protection_string,
	aarch64_pac_ret_subtypes,
	aarch64_branch_protect_types,
	aarch64_handle_pac_ret_leaf): Define.
	(aarch64_override_options_after_change_1): Add check for
	accepted_branch_protection_string.
	(aarch64_override_options): Add check for
	accepted_branch_protection_string.
	(aarch64_option_save): Save accepted_branch_protection_string.
	(aarch64_option_restore): Save
	accepted_branch_protection_string.
	* config/aarch64/aarch64.c (aarch64_attributes): Add branch-protection.
	* config/aarch64/aarch64.opt: Add mbranch-protection. Deprecate
	msign-return-address.
	* doc/invoke.texi: Add mbranch-protection.

gcc/testsuite/ChangeLog:

2018-12-20  Sam Tebbs<sam.tebbs@arm.com>

	* (gcc.target/aarch64/return_address_sign_1.c,
	gcc.target/aarch64/return_address_sign_2.c,
	gcc.target/aarch64/return_address_sign_3.c (__attribute__)): Change
	option to -mbranch-protection.
	* gcc.target/aarch64/(branch-protection-option.c,
	branch-protection-option-2.c, branch-protection-attr.c,
	branch-protection-attr-2.c): New file.
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 603849477063e8c70ece470404bdd34239fd6f19..784c93a8e9701a671004e3dfda463d726611c340 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -183,6 +183,12 @@ bool aarch64_pcrelative_literal_loads;
 /* Global flag for whether frame pointer is enabled.  */
 bool aarch64_use_frame_pointer;
 
+#define BRANCH_PROTECT_STR_MAX 255
+char *accepted_branch_protection_string = NULL;
+
+static enum aarch64_parse_opt_result
+aarch64_parse_branch_protection (const char*, char**);
+
 /* Support for command line parsing of boolean flags in the tuning
    structures.  */
 struct aarch64_flag_desc
@@ -1170,6 +1176,79 @@ aarch64_cc;
 
 #define AARCH64_INVERSE_CONDITION_CODE(X) ((aarch64_cc) (((int) X) ^ 1))
 
+struct aarch64_branch_protect_type
+{
+  /* The type's name that the user passes to the branch-protection option
+    string.  */
+  const char* name;
+  /* Function to handle the protection type and set global variables.
+    First argument is the string token corresponding with this type and the
+    second argument is the next token in the option string.
+    Return values:
+    * AARCH64_PARSE_OK: Handling was sucessful.
+    * AARCH64_INVALID_ARG: The type is invalid in this context and the caller
+      should print an error.
+    * AARCH64_INVALID_FEATURE: The type is invalid and the handler prints its
+      own error.  */
+  enum aarch64_parse_opt_result (*handler)(char*, char*);
+  /* A list of types that can follow this type in the option string.  */
+  const aarch64_branch_protect_type* subtypes;
+  unsigned int num_subtypes;
+};
+
+static enum aarch64_parse_opt_result
+aarch64_handle_no_branch_protection (char* str, char* rest)
+{
+  aarch64_ra_sign_scope = AARCH64_FUNCTION_NONE;
+  if (rest)
+    {
+      error ("unexpected %<%s%> after %<%s%>", rest, str);
+      return AARCH64_PARSE_INVALID_FEATURE;
+    }
+  return AARCH64_PARSE_OK;
+}
+
+static enum aarch64_parse_opt_result
+aarch64_handle_standard_branch_protection (char* str, char* rest)
+{
+  aarch64_ra_sign_scope = AARCH64_FUNCTION_NON_LEAF;
+  if (rest)
+    {
+      error ("unexpected %<%s%> after %<%s%>", rest, str);
+      return AARCH64_PARSE_INVALID_FEATURE;
+    }
+  return AARCH64_PARSE_OK;
+}
+
+static enum aarch64_parse_opt_result
+aarch64_handle_pac_ret_protection (char* str ATTRIBUTE_UNUSED,
+				    char* rest ATTRIBUTE_UNUSED)
+{
+  aarch64_ra_sign_scope = AARCH64_FUNCTION_NON_LEAF;
+  return AARCH64_PARSE_OK;
+}
+
+static enum aarch64_parse_opt_result
+aarch64_handle_pac_ret_leaf (char* str ATTRIBUTE_UNUSED,
+			      char* rest ATTRIBUTE_UNUSED)
+{
+  aarch64_ra_sign_scope = AARCH64_FUNCTION_ALL;
+  return AARCH64_PARSE_OK;
+}
+
+static const struct aarch64_branch_protect_type aarch64_pac_ret_subtypes[] = {
+  { "leaf", aarch64_handle_pac_ret_leaf, NULL, 0 },
+  { NULL, NULL, NULL, 0 }
+};
+
+static const struct aarch64_branch_protect_type aarch64_branch_protect_types[] = {
+  { "none", aarch64_handle_no_branch_protection, NULL, 0 },
+  { "standard", aarch64_handle_standard_branch_protection, NULL, 0 },
+  { "pac-ret", aarch64_handle_pac_ret_protection, aarch64_pac_ret_subtypes,
+    ARRAY_SIZE (aarch64_pac_ret_subtypes) },
+  { NULL, NULL, NULL, 0 }
+};
+
 /* The condition codes of the processor, and the inverse function.  */
 static const char * const aarch64_condition_codes[] =
 {
@@ -11099,6 +11178,12 @@ aarch64_parse_override_string (const char* input_string,
 static void
 aarch64_override_options_after_change_1 (struct gcc_options *opts)
 {
+  if (accepted_branch_protection_string)
+    {
+      opts->x_aarch64_branch_protection_string
+	= xstrdup (accepted_branch_protection_string);
+    }
+
   /* PR 70044: We have to be careful about being called multiple times for the
      same function.  This means all changes should be repeatable.  */
 
@@ -11384,6 +11469,110 @@ aarch64_validate_mcpu (const char *str, const struct processor **res,
   return false;
 }
 
+/* Parses CONST_STR for branch protection features specified in
+   aarch64_branch_protect_types, and set any global variables required.  Returns
+   the parsing result and assigns LAST_STR to the last processed token from
+   CONST_STR so that it can be used for error reporting.  */
+
+static enum
+aarch64_parse_opt_result aarch64_parse_branch_protection (const char *const_str,
+							  char** last_str)
+{
+  char *str_root = xstrdup (const_str);
+  char* token_save = NULL;
+  char *str = strtok_r (str_root, "+", &token_save);
+  enum aarch64_parse_opt_result res = AARCH64_PARSE_OK;
+  if (!str)
+    res = AARCH64_PARSE_MISSING_ARG;
+  else
+    {
+      char *next_str = strtok_r (NULL, "+", &token_save);
+      /* Reset the branch protection features to their defaults.  */
+      aarch64_handle_no_branch_protection (NULL, NULL);
+
+      while (str && res == AARCH64_PARSE_OK)
+	{
+	  const aarch64_branch_protect_type* type = aarch64_branch_protect_types;
+	  bool found = false;
+	  /* Search for this type.  */
+	  while (type && type->name && !found && res == AARCH64_PARSE_OK)
+	    {
+	      if (strcmp (str, type->name) == 0)
+		{
+		  found = true;
+		  res = type->handler (str, next_str);
+		  str = next_str;
+		  next_str = strtok_r (NULL, "+", &token_save);
+		}
+	      else
+		type++;
+	    }
+	  if (found && res == AARCH64_PARSE_OK)
+	    {
+	      bool found_subtype = true;
+	      /* Loop through each token until we find one that isn't a
+		 subtype.  */
+	      while (found_subtype)
+		{
+		  found_subtype = false;
+		  const aarch64_branch_protect_type *subtype = type->subtypes;
+		  /* Search for the subtype.  */
+		  while (str && subtype && subtype->name && !found_subtype
+			  && res == AARCH64_PARSE_OK)
+		    {
+		      if (strcmp (str, subtype->name) == 0)
+			{
+			  found_subtype = true;
+			  res = subtype->handler (str, next_str);
+			  str = next_str;
+			  next_str = strtok_r (NULL, "+", &token_save);
+			}
+		      else
+			subtype++;
+		    }
+		}
+	    }
+	  else if (!found)
+	    res = AARCH64_PARSE_INVALID_ARG;
+	}
+    }
+  /* Copy the last processed token into the argument to pass it back.
+    Used by option and attribute validation to print the offending token.  */
+  if (last_str)
+    {
+      if (str) strcpy (*last_str, str);
+      else *last_str = NULL;
+    }
+  if (res == AARCH64_PARSE_OK)
+    {
+      /* If needed, alloc the accepted string then copy in const_str.
+	Used by override_option_after_change_1.  */
+      if (!accepted_branch_protection_string)
+	accepted_branch_protection_string = (char *) xmalloc (
+						      BRANCH_PROTECT_STR_MAX
+							+ 1);
+      strncpy (accepted_branch_protection_string, const_str,
+		BRANCH_PROTECT_STR_MAX + 1);
+      /* Forcibly null-terminate.  */
+      accepted_branch_protection_string[BRANCH_PROTECT_STR_MAX] = '\0';
+    }
+  return res;
+}
+
+static bool
+aarch64_validate_mbranch_protection (const char *const_str)
+{
+  char *str = (char *) xmalloc (strlen (const_str));
+  enum aarch64_parse_opt_result res =
+    aarch64_parse_branch_protection (const_str, &str);
+  if (res == AARCH64_PARSE_INVALID_ARG)
+    error ("invalid arg %<%s%> for %<-mbranch-protection=%>", str);
+  else if (res == AARCH64_PARSE_MISSING_ARG)
+    error ("missing arg for %<-mbranch-protection=%>");
+  free (str);
+  return res == AARCH64_PARSE_OK;
+}
+
 /* Validate a command-line -march option.  Parse the arch and extensions
    (if any) specified in STR and throw errors if appropriate.  Put the
    results, if they are valid, in RES and ISA_FLAGS.  Return whether the
@@ -11518,6 +11707,9 @@ aarch64_override_options (void)
   selected_arch = NULL;
   selected_tune = NULL;
 
+  if (aarch64_branch_protection_string)
+    aarch64_validate_mbranch_protection (aarch64_branch_protection_string);
+
   /* -mcpu=CPU is shorthand for -march=ARCH_FOR_CPU, -mtune=CPU.
      If either of -march or -mtune is given, they override their
      respective component of -mcpu.  */
@@ -11690,6 +11882,8 @@ static void
 aarch64_option_save (struct cl_target_option *ptr, struct gcc_options *opts)
 {
   ptr->x_aarch64_override_tune_string = opts->x_aarch64_override_tune_string;
+  ptr->x_aarch64_branch_protection_string
+    = opts->x_aarch64_branch_protection_string;
 }
 
 /* Implements TARGET_OPTION_RESTORE.  Restore the backend codegen decisions
@@ -11703,6 +11897,13 @@ aarch64_option_restore (struct gcc_options *opts, struct cl_target_option *ptr)
   opts->x_explicit_arch = ptr->x_explicit_arch;
   selected_arch = aarch64_get_arch (ptr->x_explicit_arch);
   opts->x_aarch64_override_tune_string = ptr->x_aarch64_override_tune_string;
+  opts->x_aarch64_branch_protection_string
+    = ptr->x_aarch64_branch_protection_string;
+  if (opts->x_aarch64_branch_protection_string)
+    {
+      aarch64_parse_branch_protection (opts->x_aarch64_branch_protection_string,
+					NULL);
+    }
 
   aarch64_override_options_internal (opts);
 }
@@ -11897,6 +12098,37 @@ aarch64_handle_attr_cpu (const char *str)
   return false;
 }
 
+/* Handle the argument STR to the branch-protection= attribute.  */
+
+ static bool
+ aarch64_handle_attr_branch_protection (const char* str)
+ {
+  char *err_str = (char *) xmalloc (strlen (str));
+  enum aarch64_parse_opt_result res = aarch64_parse_branch_protection (str,
+								      &err_str);
+  bool success = false;
+  switch (res)
+    {
+     case AARCH64_PARSE_MISSING_ARG:
+       error ("missing argument to %<target(\"branch-protection=\")%> pragma or"
+	      " attribute");
+       break;
+     case AARCH64_PARSE_INVALID_ARG:
+       error ("invalid protection type (\"%s\") in %<target(\"branch-protection"
+	      "=\")%> pragma or attribute", err_str);
+       break;
+     case AARCH64_PARSE_OK:
+       success = true;
+      /* Fall through.  */
+     case AARCH64_PARSE_INVALID_FEATURE:
+       break;
+     default:
+       gcc_unreachable ();
+    }
+  free (err_str);
+  return success;
+ }
+
 /* Handle the argument STR to the tune= target attribute.  */
 
 static bool
@@ -11995,6 +12227,8 @@ static const struct aarch64_attribute_info aarch64_attributes[] =
   { "cpu", aarch64_attr_custom, false, aarch64_handle_attr_cpu, OPT_mcpu_ },
   { "tune", aarch64_attr_custom, false, aarch64_handle_attr_tune,
      OPT_mtune_ },
+  { "branch-protection", aarch64_attr_custom, false,
+     aarch64_handle_attr_branch_protection, OPT_mbranch_protection_ },
   { "sign-return-address", aarch64_attr_enum, false, NULL,
      OPT_msign_return_address_ },
   { NULL, aarch64_attr_custom, false, NULL, OPT____ }
diff --git a/gcc/config/aarch64/aarch64.opt b/gcc/config/aarch64/aarch64.opt
index b2e80cbf6f1f9727c4309874b1122f975fb6b9be..9460636d93b67af1525f028176aa78e6fed4e45f 100644
--- a/gcc/config/aarch64/aarch64.opt
+++ b/gcc/config/aarch64/aarch64.opt
@@ -149,8 +149,12 @@ mpc-relative-literal-loads
 Target Report Save Var(pcrelative_literal_loads) Init(2) Save
 PC relative literal loads.
 
+mbranch-protection=
+Target RejectNegative Joined Var(aarch64_branch_protection_string) Save
+Use branch-protection features.
+
 msign-return-address=
-Target RejectNegative Report Joined Enum(aarch64_ra_sign_scope_t) Var(aarch64_ra_sign_scope) Init(AARCH64_FUNCTION_NONE) Save
+Target Deprecated RejectNegative Joined Enum(aarch64_ra_sign_scope_t) Var(aarch64_ra_sign_scope) Init(AARCH64_FUNCTION_NONE) Save
 Select return address signing scope.
 
 Enum
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index ac2ee59d92c3d5bd0e9deb854ba9fcb3dcee4ec9..99c67e3896dcf93c90384b08198523e94a754f7e 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -630,6 +630,7 @@ Objective-C and Objective-C++ Dialects}.
 -mlow-precision-recip-sqrt  -mlow-precision-sqrt  -mlow-precision-div @gol
 -mpc-relative-literal-loads @gol
 -msign-return-address=@var{scope} @gol
+-mbranch-protection=@var{none}|@var{standard}|@var{pac-ret}[+@var{leaf}] @gol
 -march=@var{name}  -mcpu=@var{name}  -mtune=@var{name}  @gol
 -moverride=@var{string}  -mverbose-cost-dump  -mtrack-speculation} 
 
@@ -15700,7 +15701,21 @@ Select the function scope on which return address signing will be applied.
 Permissible values are @samp{none}, which disables return address signing,
 @samp{non-leaf}, which enables pointer signing for functions which are not leaf
 functions, and @samp{all}, which enables pointer signing for all functions.  The
-default value is @samp{none}.
+default value is @samp{none}. This option has been deprecated by
+-mbranch-protection.
+
+@item -mbranch-protection=@var{none}|@var{standard}|@var{pac-ret}[+@var{leaf}]
+@opindex mbranch-protection
+Select the branch protection features to use.
+@samp{none} is the default and turns off all types of branch protection.
+@samp{standard} turns on all types of branch protection features.  If a feature
+has additional tuning options, then @samp{standard} sets it to its standard
+level.
+@samp{pac-ret[+@var{leaf}]} turns on return address signing to its standard
+level: signing functions that save the return address to memory (non-leaf
+functions will practically always do this) using the a-key.  The optional
+argument @samp{leaf} can be used to extend the signing to include leaf
+functions.
 
 @item -msve-vector-bits=@var{bits}
 @opindex msve-vector-bits
diff --git a/gcc/testsuite/gcc.target/aarch64/branch-protection-attr-2.c b/gcc/testsuite/gcc.target/aarch64/branch-protection-attr-2.c
new file mode 100644
index 0000000000000000000000000000000000000000..19b3511ab6111a895383f5ddf93644110c3971c6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/branch-protection-attr-2.c
@@ -0,0 +1,16 @@
+/* { dg-do "compile" } */
+
+void __attribute__ ((target("branch-protection=pac-ret+leaf,branch-protection=none")))
+foo ()
+{
+}
+
+void __attribute__ ((target("branch-protection=pac-ret,branch-protection=none")))
+foo2 ()
+{
+  /* Function call here to make this a non-leaf function, so that it is covered by pac-ret.  */
+  foo ();
+}
+
+/* { dg-final { scan-assembler-not "\tautiasp\t" } } */
+/* { dg-final { scan-assembler-not "\tpaciasp\t" } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/branch-protection-attr.c b/gcc/testsuite/gcc.target/aarch64/branch-protection-attr.c
new file mode 100644
index 0000000000000000000000000000000000000000..229ce1ca7bebce060204946682af175389527193
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/branch-protection-attr.c
@@ -0,0 +1,22 @@
+/* { dg-do "compile" } */
+
+void __attribute__ ((target("branch-protection=leaf")))
+foo1 ()
+{
+}
+/* { dg-error {invalid protection type \("leaf"\) in 'target\("branch-protection="\)' pragma or attribute} "" { target *-*-* } 5 } */
+/* { dg-error {pragma or attribute 'target\("branch-protection=leaf"\)' is not valid} "" { target *-*-* } 5 } */
+
+void __attribute__ ((target("branch-protection=none+pac-ret")))
+foo2 ()
+{
+}
+/* { dg-error "unexpected 'pac-ret' after 'none'" "" { target *-*-* } 12 } */
+/* { dg-error {pragma or attribute 'target\("branch-protection=none\+pac-ret"\)' is not valid} "" { target *-*-* } 12 } */
+
+void __attribute__ ((target("branch-protection=")))
+foo3 ()
+{
+}
+/* { dg-error {missing argument to 'target\("branch-protection="\)' pragma or attribute} "" { target *-*-* } 19 } */
+/* { dg-error {pragma or attribute 'target\("branch-protection="\)' is not valid} "" { target *-*-* } 19 } */
diff --git a/gcc/testsuite/gcc.target/aarch64/branch-protection-option-2.c b/gcc/testsuite/gcc.target/aarch64/branch-protection-option-2.c
new file mode 100644
index 0000000000000000000000000000000000000000..281851136520ece286186fd18c1a64b984f0b3e8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/branch-protection-option-2.c
@@ -0,0 +1,9 @@
+/* { dg-do "compile" } */
+/* { dg-options "-mbranch-protection=pac-ret+leaf -mbranch-protection=none" } */
+
+void foo2 ()
+{
+}
+
+/* { dg-final { scan-assembler-not "\tautiasp\t" } } */
+/* { dg-final { scan-assembler-not "\tpaciasp\t" } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/branch-protection-option.c b/gcc/testsuite/gcc.target/aarch64/branch-protection-option.c
new file mode 100644
index 0000000000000000000000000000000000000000..1b3bf4ee2b88a6e89d78f99766889904849a89db
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/branch-protection-option.c
@@ -0,0 +1,4 @@
+/* { dg-do "compile" } */
+/* { dg-options "-mbranch-protection=leaf -mbranch-protection=none+pac-ret" } */
+
+/* { dg-error "unexpected 'pac-ret' after 'none'"  "" { target *-*-* } 0 } */
diff --git a/gcc/testsuite/gcc.target/aarch64/return_address_sign_1.c b/gcc/testsuite/gcc.target/aarch64/return_address_sign_1.c
index f87c3d28d1edff473a787a39a436e57076f97508..0140bee194f5a3ec53e794984c2f9b0e96bdbb63 100644
--- a/gcc/testsuite/gcc.target/aarch64/return_address_sign_1.c
+++ b/gcc/testsuite/gcc.target/aarch64/return_address_sign_1.c
@@ -1,6 +1,6 @@
 /* Testing return address signing where no combined instructions used.  */
 /* { dg-do compile } */
-/* { dg-options "-O2 -msign-return-address=all" } */
+/* { dg-options "-O2 -mbranch-protection=pac-ret+leaf" } */
 /* { dg-require-effective-target lp64 } */
 
 int foo (int);
diff --git a/gcc/testsuite/gcc.target/aarch64/return_address_sign_2.c b/gcc/testsuite/gcc.target/aarch64/return_address_sign_2.c
index c5c1439b92e6637f85c47c6161cd797c0d68df25..a4bc5b4533382d3d21085a763028576f72531ed7 100644
--- a/gcc/testsuite/gcc.target/aarch64/return_address_sign_2.c
+++ b/gcc/testsuite/gcc.target/aarch64/return_address_sign_2.c
@@ -1,6 +1,6 @@
 /* Testing return address signing where combined instructions used.  */
 /* { dg-do compile } */
-/* { dg-options "-O2 -msign-return-address=all" } */
+/* { dg-options "-O2 -mbranch-protection=pac-ret+leaf" } */
 /* { dg-require-effective-target lp64 } */
 
 int foo (int);
diff --git a/gcc/testsuite/gcc.target/aarch64/return_address_sign_3.c b/gcc/testsuite/gcc.target/aarch64/return_address_sign_3.c
index 7d9ec6eebd1ce452013d2895a551671c59e98f0c..e39ed34ab1c13d1368f4a625b4a466eb76354ef8 100644
--- a/gcc/testsuite/gcc.target/aarch64/return_address_sign_3.c
+++ b/gcc/testsuite/gcc.target/aarch64/return_address_sign_3.c
@@ -1,17 +1,17 @@
 /* Testing the disable of return address signing.  */
 /* { dg-do compile } */
-/* { dg-options "-O2 -msign-return-address=all" } */
+/* { dg-options "-O2 -mbranch-protection=pac-ret+leaf" } */
 /* { dg-require-effective-target lp64 } */
 
 int bar (int, int);
 
-int __attribute__ ((target ("arch=armv8.3-a, sign-return-address=non-leaf")))
+int __attribute__ ((target ("arch=armv8.3-a, branch-protection=pac-ret")))
 func1_leaf (int a, int b, int c, int d)
 {
   return a + b + c + d;
 }
 
-int __attribute__ ((target ("arch=armv8.3-a, sign-return-address=none")))
+int __attribute__ ((target ("arch=armv8.3-a, branch-protection=none")))
 func2_none (int a, int b, int c, int d)
 {
   return c + bar (a, b) + d;
Sam Tebbs Jan. 4, 2019, 4:55 p.m. UTC | #5
On 12/20/18 4:38 PM, Sam Tebbs wrote:

> On 11/22/18 4:54 PM, Sam Tebbs wrote:
>> On 11/12/18 6:24 PM, Sudakshina Das wrote:
>>> Hi Sam
>>>
>>> On 02/11/18 17:31, Sam Tebbs wrote:
>>>> Hi all,
>>>>
>>>> The -mbranch-protection option combines the functionality of
>>>> -msign-return-address and the BTI features new in Armv8.5 to better reflect
>>>> their relationship. This new option therefore supersedes and deprecates the
>>>> existing -msign-return-address option.
>>>>
>>>> -mbranch-protection=[none|standard|<types>] - Turns on different types of branch
>>>> protection available where:
>>>>
>>>>          * "none": Turn of all types of branch protection
>>>>          * "standard" : Turns on all the types of protection to their respective
>>>>            standard levels.
>>>>          * <types> can be "+" separated protection types:
>>>>
>>>>          	* "bti" : Branch Target Identification Mechanism.
>>>> 	* "pac-ret{+leaf+b-key}": Return Address Signing. The default return
>>>> 	  address signing is enabled by signing functions that save the return
>>>> 	  address to memory (non-leaf functions will practically always do this)
>>>> 	  using the a-key. The optional tuning arguments allow the user to
>>>> 	  extend the scope of return address signing to include leaf functions
>>>> 	  and to change the key to b-key. The tuning arguments must proceed the
>>>> 	  protection type "pac-ret".
>>>>
>>>> Thus -mbranch-protection=standard -> -mbranch-protection=bti+pac-ret.
>>>>
>>>> Its mapping to -msign-return-address is as follows:
>>>>
>>>>          * -mbranch-protection=none -> -msign-return-address=none
>>>>          * -mbranch-protection=standard -> -msign-return-address=leaf
>>>>          * -mbranch-protection=pac-ret -> -msign-return-address=non-leaf
>>>>          * -mbranch-protection=pac-ret+leaf -> -msign-return-address=all
>>>>
>>>> This patch implements the option's skeleton and the "none", "standard" and
>>>> "pac-ret" types (along with its "leaf" subtype).
>>>>
>>>> The previous patch in this series is here:
>>>> https://gcc.gnu.org/ml/gcc-patches/2018-11/msg00103.html
>>>>
>>>> Bootstrapped successfully and tested on aarch64-none-elf with no regressions.
>>>>
>>>> OK for trunk?
>>>>
>>> Thank for doing this. I am not a maintainer so you will need a
>>> maintainer's approval. Only nit, that I would add is that it would
>>> be good to have more test coverage, specially for the new parsing
>>> functions that have been added and the errors that are added.
>>>
>>> Example checking a few valid and invalid combinations of the options
>>> like:
>>> -mbranch-protection=pac-ret -mbranch-protection=none //disables
>>> everything
>>> -mbranch-protection=leaf  //errors out
>>> -mbranch-protection=none+pac-ret //errors out
>>> ... etc
>>> Also instead of removing all the old deprecated options, you can keep
>>> one (or a copy of one) to check for the deprecated warning.
>> Hi Sudi,
>>
>> Thanks for the feedback, I've incorporated your suggestions into the
>> attached patch and the updated changelog.
>>
>> gcc/ChangeLog:
>>
>> 2018-11-22  Sam Tebbs<sam.tebbs@arm.com>
>>
>> 	* config/aarch64/aarch64.c (BRANCH_PROTEC_STR_MAX,
>> 	aarch64_parse_branch_protection,
>> 	struct aarch64_branch_protec_type,
>> 	aarch64_handle_no_branch_protection,
>> 	aarch64_handle_standard_branch_protection,
>> 	aarch64_validate_mbranch_protection,
>> 	aarch64_handle_pac_ret_protection,
>> 	aarch64_handle_attr_branch_protection,
>> 	accepted_branch_protection_string,
>> 	aarch64_pac_ret_subtypes,
>> 	aarch64_branch_protec_types,
>> 	aarch64_handle_pac_ret_leaf): Define.
>> 	(aarch64_override_options_after_change_1): Add check for
>> 	accepted_branch_protection_string.
>> 	(aarch64_override_options): Add check for
>> 	accepted_branch_protection_string.
>> 	(aarch64_option_save): Save accepted_branch_protection_string.
>> 	(aarch64_option_restore): Save
>> 	accepted_branch_protection_string.
>> 	* config/aarch64/aarch64.c (aarch64_attributes): Add branch-protection.
>> 	* config/aarch64/aarch64.opt: Add mbranch-protection. Deprecate
>> 	msign-return-address.
>> 	* doc/invoke.texi: Add mbranch-protection.
>>
>> gcc/testsuite/ChangeLog:
>>
>> 2018-11-22  Sam Tebbs<sam.tebbs@arm.com>
>>
>> 	* (gcc.target/aarch64/return_address_sign_1.c,
>> 	gcc.target/aarch64/return_address_sign_2.c,
>> 	gcc.target/aarch64/return_address_sign_3.c (__attribute__)): Change
>> 	option to -mbranch-protection.
>> 	* gcc.target/aarch64/(branch-protection-option.c,
>> 	branch-protection-option-2.c, branch-protection-attr.c,
>> 	branch-protection-attr-2.c): New file.
> Hi all,
>
> Attached is an updated patch with branch_protec_type renamed to
> branch_protect_type, some unneeded ATTRIBUTE_USED removed and an added
> use of ARRAY_SIZE.
>
> Below is the updated changelog.
>
> OK for trunk? I have committed the preceding patch in the series.
>
> gcc/ChangeLog:
>
> 2018-12-20  Sam Tebbs<sam.tebbs@arm.com>
>
> 	* config/aarch64/aarch64.c (BRANCH_PROTECT_STR_MAX,
> 	aarch64_parse_branch_protection,
> 	struct aarch64_branch_protect_type,
> 	aarch64_handle_no_branch_protection,
> 	aarch64_handle_standard_branch_protection,
> 	aarch64_validate_mbranch_protection,
> 	aarch64_handle_pac_ret_protection,
> 	aarch64_handle_attr_branch_protection,
> 	accepted_branch_protection_string,
> 	aarch64_pac_ret_subtypes,
> 	aarch64_branch_protect_types,
> 	aarch64_handle_pac_ret_leaf): Define.
> 	(aarch64_override_options_after_change_1): Add check for
> 	accepted_branch_protection_string.
> 	(aarch64_override_options): Add check for
> 	accepted_branch_protection_string.
> 	(aarch64_option_save): Save accepted_branch_protection_string.
> 	(aarch64_option_restore): Save
> 	accepted_branch_protection_string.
> 	* config/aarch64/aarch64.c (aarch64_attributes): Add branch-protection.
> 	* config/aarch64/aarch64.opt: Add mbranch-protection. Deprecate
> 	msign-return-address.
> 	* doc/invoke.texi: Add mbranch-protection.
>
> gcc/testsuite/ChangeLog:
>
> 2018-12-20  Sam Tebbs<sam.tebbs@arm.com>
>
> 	* (gcc.target/aarch64/return_address_sign_1.c,
> 	gcc.target/aarch64/return_address_sign_2.c,
> 	gcc.target/aarch64/return_address_sign_3.c (__attribute__)): Change
> 	option to -mbranch-protection.
> 	* gcc.target/aarch64/(branch-protection-option.c,
> 	branch-protection-option-2.c, branch-protection-attr.c,
> 	branch-protection-attr-2.c): New file.
>
ping
James Greenhalgh Jan. 7, 2019, 6:11 p.m. UTC | #6
On Thu, Dec 20, 2018 at 10:38:42AM -0600, Sam Tebbs wrote:
> On 11/22/18 4:54 PM, Sam Tebbs wrote:

<snip>

> 
> Hi all,
> 
> Attached is an updated patch with branch_protec_type renamed to 
> branch_protect_type, some unneeded ATTRIBUTE_USED removed and an added 
> use of ARRAY_SIZE.
> 
> Below is the updated changelog.
> 
> OK for trunk? I have committed the preceding patch in the series.


OK. Please get this in soon as we really want to be closing down for Stage 4
(and fix a few bugs in return :-) ).

Thanks,
James

> 
> gcc/ChangeLog:
> 
> 2018-12-20  Sam Tebbs<sam.tebbs@arm.com>
> 
> 	* config/aarch64/aarch64.c (BRANCH_PROTECT_STR_MAX,
> 	aarch64_parse_branch_protection,
> 	struct aarch64_branch_protect_type,
> 	aarch64_handle_no_branch_protection,
> 	aarch64_handle_standard_branch_protection,
> 	aarch64_validate_mbranch_protection,
> 	aarch64_handle_pac_ret_protection,
> 	aarch64_handle_attr_branch_protection,
> 	accepted_branch_protection_string,
> 	aarch64_pac_ret_subtypes,
> 	aarch64_branch_protect_types,
> 	aarch64_handle_pac_ret_leaf): Define.
> 	(aarch64_override_options_after_change_1): Add check for
> 	accepted_branch_protection_string.
> 	(aarch64_override_options): Add check for
> 	accepted_branch_protection_string.
> 	(aarch64_option_save): Save accepted_branch_protection_string.
> 	(aarch64_option_restore): Save
> 	accepted_branch_protection_string.
> 	* config/aarch64/aarch64.c (aarch64_attributes): Add branch-protection.
> 	* config/aarch64/aarch64.opt: Add mbranch-protection. Deprecate
> 	msign-return-address.
> 	* doc/invoke.texi: Add mbranch-protection.
> 
> gcc/testsuite/ChangeLog:
> 
> 2018-12-20  Sam Tebbs<sam.tebbs@arm.com>
> 
> 	* (gcc.target/aarch64/return_address_sign_1.c,
> 	gcc.target/aarch64/return_address_sign_2.c,
> 	gcc.target/aarch64/return_address_sign_3.c (__attribute__)): Change
> 	option to -mbranch-protection.
> 	* gcc.target/aarch64/(branch-protection-option.c,
> 	branch-protection-option-2.c, branch-protection-attr.c,
> 	branch-protection-attr-2.c): New file.
>
Sam Tebbs Jan. 8, 2019, 10:31 a.m. UTC | #7
On 1/7/19 6:11 PM, James Greenhalgh wrote:

> On Thu, Dec 20, 2018 at 10:38:42AM -0600, Sam Tebbs wrote:
>> On 11/22/18 4:54 PM, Sam Tebbs wrote:
> <snip>
>
>> Hi all,
>>
>> Attached is an updated patch with branch_protec_type renamed to
>> branch_protect_type, some unneeded ATTRIBUTE_USED removed and an added
>> use of ARRAY_SIZE.
>>
>> Below is the updated changelog.
>>
>> OK for trunk? I have committed the preceding patch in the series.
>
> OK. Please get this in soon as we really want to be closing down for Stage 4
> (and fix a few bugs in return :-) ).
>
> Thanks,
> James
Thanks James, committed as r267717.
>
>> gcc/ChangeLog:
>>
>> 2018-12-20  Sam Tebbs<sam.tebbs@arm.com>
>>
>> 	* config/aarch64/aarch64.c (BRANCH_PROTECT_STR_MAX,
>> 	aarch64_parse_branch_protection,
>> 	struct aarch64_branch_protect_type,
>> 	aarch64_handle_no_branch_protection,
>> 	aarch64_handle_standard_branch_protection,
>> 	aarch64_validate_mbranch_protection,
>> 	aarch64_handle_pac_ret_protection,
>> 	aarch64_handle_attr_branch_protection,
>> 	accepted_branch_protection_string,
>> 	aarch64_pac_ret_subtypes,
>> 	aarch64_branch_protect_types,
>> 	aarch64_handle_pac_ret_leaf): Define.
>> 	(aarch64_override_options_after_change_1): Add check for
>> 	accepted_branch_protection_string.
>> 	(aarch64_override_options): Add check for
>> 	accepted_branch_protection_string.
>> 	(aarch64_option_save): Save accepted_branch_protection_string.
>> 	(aarch64_option_restore): Save
>> 	accepted_branch_protection_string.
>> 	* config/aarch64/aarch64.c (aarch64_attributes): Add branch-protection.
>> 	* config/aarch64/aarch64.opt: Add mbranch-protection. Deprecate
>> 	msign-return-address.
>> 	* doc/invoke.texi: Add mbranch-protection.
>>
>> gcc/testsuite/ChangeLog:
>>
>> 2018-12-20  Sam Tebbs<sam.tebbs@arm.com>
>>
>> 	* (gcc.target/aarch64/return_address_sign_1.c,
>> 	gcc.target/aarch64/return_address_sign_2.c,
>> 	gcc.target/aarch64/return_address_sign_3.c (__attribute__)): Change
>> 	option to -mbranch-protection.
>> 	* gcc.target/aarch64/(branch-protection-option.c,
>> 	branch-protection-option-2.c, branch-protection-attr.c,
>> 	branch-protection-attr-2.c): New file.
>>
diff mbox series

Patch

diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index b44ee40115dce526c7cc302b2a47c28ab8b41508..121348dbd909f42717efea163ea6b7c545f5b1c7 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -183,6 +183,12 @@  bool aarch64_pcrelative_literal_loads;
 /* Global flag for whether frame pointer is enabled.  */
 bool aarch64_use_frame_pointer;
 
+#define BRANCH_PROTEC_STR_MAX 255
+char *accepted_branch_protection_string = NULL;
+
+static enum aarch64_parse_opt_result
+aarch64_parse_branch_protection (const char*, char**);
+
 /* Support for command line parsing of boolean flags in the tuning
    structures.  */
 struct aarch64_flag_desc
@@ -1108,6 +1114,80 @@  aarch64_cc;
 
 #define AARCH64_INVERSE_CONDITION_CODE(X) ((aarch64_cc) (((int) X) ^ 1))
 
+struct aarch64_branch_protec_type
+{
+  /* The type's name that the user passes to the branch-protection option
+    string.  */
+  const char* name;
+  /* Function to handle the protection type and set global variables.
+    First argument is the string token corresponding with this type and the
+    second argument is the next token in the option string.
+    Return values:
+    * AARCH64_PARSE_OK: Handling was sucessful.
+    * AARCH64_INVALID_ARG: The type is invalid in this context and the caller
+      should print an error.
+    * AARCH64_INVALID_FEATURE: The type is invalid and the handler prints its
+      own error.  */
+  enum aarch64_parse_opt_result (*handler)(char*, char*);
+  /* A list of types that can follow this type in the option string.  */
+  const aarch64_branch_protec_type* subtypes;
+  unsigned int num_subtypes;
+};
+
+static enum aarch64_parse_opt_result
+aarch64_handle_no_branch_protection (char* str ATTRIBUTE_UNUSED, char* rest)
+{
+  aarch64_ra_sign_scope = AARCH64_FUNCTION_NONE;
+  if (rest)
+    {
+      error ("unexpected %<%s%> after %<%s%>", rest, str);
+      return AARCH64_PARSE_INVALID_FEATURE;
+    }
+  return AARCH64_PARSE_OK;
+}
+
+static enum aarch64_parse_opt_result
+aarch64_handle_standard_branch_protection (char* str ATTRIBUTE_UNUSED,
+					    char* rest ATTRIBUTE_UNUSED)
+{
+  aarch64_ra_sign_scope = AARCH64_FUNCTION_NON_LEAF;
+  if (rest)
+    {
+      error ("unexpected %<%s%> after %<%s%>", rest, str);
+      return AARCH64_PARSE_INVALID_FEATURE;
+    }
+  return AARCH64_PARSE_OK;
+}
+
+static enum aarch64_parse_opt_result
+aarch64_handle_pac_ret_protection (char* str ATTRIBUTE_UNUSED,
+				    char* rest ATTRIBUTE_UNUSED)
+{
+  aarch64_ra_sign_scope = AARCH64_FUNCTION_NON_LEAF;
+  return AARCH64_PARSE_OK;
+}
+
+static enum aarch64_parse_opt_result
+aarch64_handle_pac_ret_leaf (char* str ATTRIBUTE_UNUSED,
+			      char* rest ATTRIBUTE_UNUSED)
+{
+  aarch64_ra_sign_scope = AARCH64_FUNCTION_ALL;
+  return AARCH64_PARSE_OK;
+}
+
+static const struct aarch64_branch_protec_type aarch64_pac_ret_subtypes[] = {
+  { "leaf", aarch64_handle_pac_ret_leaf, NULL, 0 },
+  { NULL, NULL, NULL, 0 }
+};
+
+static const struct aarch64_branch_protec_type aarch64_branch_protec_types[] = {
+  { "none", aarch64_handle_no_branch_protection, NULL, 0 },
+  { "standard", aarch64_handle_standard_branch_protection, NULL, 0 },
+  { "pac-ret", aarch64_handle_pac_ret_protection, aarch64_pac_ret_subtypes,
+    sizeof (aarch64_pac_ret_subtypes) / sizeof (aarch64_branch_protec_type) },
+  { NULL, NULL, NULL, 0 }
+};
+
 /* The condition codes of the processor, and the inverse function.  */
 static const char * const aarch64_condition_codes[] =
 {
@@ -10894,6 +10974,12 @@  aarch64_parse_override_string (const char* input_string,
 static void
 aarch64_override_options_after_change_1 (struct gcc_options *opts)
 {
+  if (accepted_branch_protection_string)
+    {
+      opts->x_aarch64_branch_protection_string
+	= xstrdup (accepted_branch_protection_string);
+    }
+
   /* PR 70044: We have to be careful about being called multiple times for the
      same function.  This means all changes should be repeatable.  */
 
@@ -11179,6 +11265,109 @@  aarch64_validate_mcpu (const char *str, const struct processor **res,
   return false;
 }
 
+/* Parses CONST_STR for branch protection features specified in
+   aarch64_branch_protec_types, and set any global variables required.  Returns
+   the parsing result and assigns LAST_STR to the last processed token from
+   CONST_STR so that it can be used for error reporting.  */
+
+static enum
+aarch64_parse_opt_result aarch64_parse_branch_protection (const char *const_str,
+							  char** last_str)
+{
+  char *str = xstrdup (const_str);
+  str = strtok (str, "+");
+  enum aarch64_parse_opt_result res = AARCH64_PARSE_OK;
+  if (!str)
+    res = AARCH64_PARSE_MISSING_ARG;
+  else
+    {
+      char *next_str = strtok (NULL, "+");
+      /* Reset the branch protection features to their defaults.  */
+      aarch64_handle_no_branch_protection (NULL, NULL);
+
+      while (str && res == AARCH64_PARSE_OK)
+	{
+	  const aarch64_branch_protec_type* type = aarch64_branch_protec_types;
+	  bool found = false;
+	  /* Search for this type.  */
+	  while (type && type->name && !found && res == AARCH64_PARSE_OK)
+	    {
+	      if (strcmp (str, type->name) == 0)
+		{
+		  found = true;
+		  res = type->handler (str, next_str);
+		  str = next_str;
+		  next_str = strtok (NULL, "+");
+		}
+	      else
+		type++;
+	    }
+	  if (found && res == AARCH64_PARSE_OK)
+	    {
+	      bool found_subtype = true;
+	      /* Loop through each token until we find one that isn't a
+		 subtype.  */
+	      while (found_subtype)
+		{
+		  found_subtype = false;
+		  const aarch64_branch_protec_type *subtype = type->subtypes;
+		  /* Search for the subtype.  */
+		  while (str && subtype && subtype->name && !found_subtype
+			  && res == AARCH64_PARSE_OK)
+		    {
+		      if (strcmp (str, subtype->name) == 0)
+			{
+			  found_subtype = true;
+			  res = subtype->handler (str, next_str);
+			  str = next_str;
+			  next_str = strtok (NULL, "+");
+			}
+		      else
+			subtype++;
+		    }
+		}
+	    }
+	  else if (!found)
+	    res = AARCH64_PARSE_INVALID_ARG;
+	}
+    }
+  /* Copy the last processed token into the argument to pass it back.
+    Used by option and attribute validation to print the offending token.  */
+  if (last_str)
+    {
+      if (str) strcpy (*last_str, str);
+      else *last_str = NULL;
+    }
+  if (res == AARCH64_PARSE_OK)
+    {
+      /* If needed, alloc the accepted string then copy in const_str.
+	Used by override_option_after_change_1.  */
+      if (!accepted_branch_protection_string)
+	accepted_branch_protection_string = (char *) xmalloc (
+						      BRANCH_PROTEC_STR_MAX
+							+ 1);
+      strncpy (accepted_branch_protection_string, const_str,
+		BRANCH_PROTEC_STR_MAX + 1);
+      /* Forcibly null-terminate.  */
+      accepted_branch_protection_string[BRANCH_PROTEC_STR_MAX] = '\0';
+    }
+  return res;
+}
+
+static bool
+aarch64_validate_mbranch_protection (const char *const_str)
+{
+  char *str = (char *) xmalloc (strlen (const_str));
+  enum aarch64_parse_opt_result res =
+    aarch64_parse_branch_protection (const_str, &str);
+  if (res == AARCH64_PARSE_INVALID_ARG)
+    error ("invalid arg %<%s%> for %<-mbranch-protection=%>", str);
+  else if (res == AARCH64_PARSE_MISSING_ARG)
+    error ("missing arg for %<-mbranch-protection=%>");
+  free (str);
+  return res == AARCH64_PARSE_OK;
+}
+
 /* Validate a command-line -march option.  Parse the arch and extensions
    (if any) specified in STR and throw errors if appropriate.  Put the
    results, if they are valid, in RES and ISA_FLAGS.  Return whether the
@@ -11313,6 +11502,9 @@  aarch64_override_options (void)
   selected_arch = NULL;
   selected_tune = NULL;
 
+  if (aarch64_branch_protection_string)
+    aarch64_validate_mbranch_protection (aarch64_branch_protection_string);
+
   /* -mcpu=CPU is shorthand for -march=ARCH_FOR_CPU, -mtune=CPU.
      If either of -march or -mtune is given, they override their
      respective component of -mcpu.  */
@@ -11475,6 +11667,8 @@  static void
 aarch64_option_save (struct cl_target_option *ptr, struct gcc_options *opts)
 {
   ptr->x_aarch64_override_tune_string = opts->x_aarch64_override_tune_string;
+  ptr->x_aarch64_branch_protection_string
+    = opts->x_aarch64_branch_protection_string;
 }
 
 /* Implements TARGET_OPTION_RESTORE.  Restore the backend codegen decisions
@@ -11488,6 +11682,13 @@  aarch64_option_restore (struct gcc_options *opts, struct cl_target_option *ptr)
   opts->x_explicit_arch = ptr->x_explicit_arch;
   selected_arch = aarch64_get_arch (ptr->x_explicit_arch);
   opts->x_aarch64_override_tune_string = ptr->x_aarch64_override_tune_string;
+  opts->x_aarch64_branch_protection_string
+    = ptr->x_aarch64_branch_protection_string;
+  if (opts->x_aarch64_branch_protection_string)
+    {
+      aarch64_parse_branch_protection (opts->x_aarch64_branch_protection_string,
+					NULL);
+    }
 
   aarch64_override_options_internal (opts);
 }
@@ -11682,6 +11883,34 @@  aarch64_handle_attr_cpu (const char *str)
   return false;
 }
 
+/* Handle the argument STR to the branch-protection= attribute.  */
+
+ static bool
+ aarch64_handle_attr_branch_protection (const char* str)
+ {
+  char *err_str = (char *) xmalloc (strlen (str));
+  enum aarch64_parse_opt_result res = aarch64_parse_branch_protection (str,
+								      &err_str);
+  switch (res)
+    {
+     case AARCH64_PARSE_MISSING_ARG:
+       error ("missing argument to %<target(\"branch-protection=\")%> pragma or\
+	      attribute");
+       break;
+     case AARCH64_PARSE_INVALID_ARG:
+       error ("invalid protection type (\"%s\") in %<target(\"branch-protection\
+	      =\")%> pragma or attribute", err_str);
+       aarch64_print_hint_for_core (str);
+       break;
+     case AARCH64_PARSE_OK:
+       return true;
+     default:
+       gcc_unreachable ();
+    }
+  free (err_str);
+  return false;
+ }
+
 /* Handle the argument STR to the tune= target attribute.  */
 
 static bool
@@ -11780,6 +12009,8 @@  static const struct aarch64_attribute_info aarch64_attributes[] =
   { "cpu", aarch64_attr_custom, false, aarch64_handle_attr_cpu, OPT_mcpu_ },
   { "tune", aarch64_attr_custom, false, aarch64_handle_attr_tune,
      OPT_mtune_ },
+  { "branch-protection", aarch64_attr_custom, false,
+     aarch64_handle_attr_branch_protection, OPT_mbranch_protection_ },
   { "sign-return-address", aarch64_attr_enum, false, NULL,
      OPT_msign_return_address_ },
   { NULL, aarch64_attr_custom, false, NULL, OPT____ }
diff --git a/gcc/config/aarch64/aarch64.opt b/gcc/config/aarch64/aarch64.opt
index b2e80cbf6f1f9727c4309874b1122f975fb6b9be..9460636d93b67af1525f028176aa78e6fed4e45f 100644
--- a/gcc/config/aarch64/aarch64.opt
+++ b/gcc/config/aarch64/aarch64.opt
@@ -149,8 +149,12 @@  mpc-relative-literal-loads
 Target Report Save Var(pcrelative_literal_loads) Init(2) Save
 PC relative literal loads.
 
+mbranch-protection=
+Target RejectNegative Joined Var(aarch64_branch_protection_string) Save
+Use branch-protection features.
+
 msign-return-address=
-Target RejectNegative Report Joined Enum(aarch64_ra_sign_scope_t) Var(aarch64_ra_sign_scope) Init(AARCH64_FUNCTION_NONE) Save
+Target Deprecated RejectNegative Joined Enum(aarch64_ra_sign_scope_t) Var(aarch64_ra_sign_scope) Init(AARCH64_FUNCTION_NONE) Save
 Select return address signing scope.
 
 Enum
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index e290128f535f3e6b515bff5a81fae0aa0d1c8baf..07cfe69dc3dd9161a2dd93089ccf52ef251208d2 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -622,6 +622,7 @@  Objective-C and Objective-C++ Dialects}.
 -mlow-precision-recip-sqrt  -mlow-precision-sqrt  -mlow-precision-div @gol
 -mpc-relative-literal-loads @gol
 -msign-return-address=@var{scope} @gol
+-mbranch-protection=@var{none}|@var{standard}|@var{pac-ret}[+@var{leaf}] @gol
 -march=@var{name}  -mcpu=@var{name}  -mtune=@var{name}  @gol
 -moverride=@var{string}  -mverbose-cost-dump -mtrack-speculation} 
 
@@ -15221,13 +15222,18 @@  accessed using a single instruction and emitted after each function.  This
 limits the maximum size of functions to 1MB.  This is enabled by default for
 @option{-mcmodel=tiny}.
 
-@item -msign-return-address=@var{scope}
-@opindex msign-return-address
-Select the function scope on which return address signing will be applied.
-Permissible values are @samp{none}, which disables return address signing,
-@samp{non-leaf}, which enables pointer signing for functions which are not leaf
-functions, and @samp{all}, which enables pointer signing for all functions.  The
-default value is @samp{none}.
+@item -mbranch-protection=@var{none}|@var{standard}|@var{pac-ret}[+@var{leaf}]
+@opindex mbranch-protection
+Select the branch protection features to use.
+@samp{none} is the default and turns off all types of branch protection.
+@samp{standard} turns on all types of branch protection features.  If a feature
+has additional tuning options, then @samp{standard} sets it to its standard
+level.
+@samp{pac-ret[+@var{leaf}]} turns on return address signing to its standard
+level: signing functions that save the return address to memory (non-leaf
+functions will practically always do this) using the a-key.  The optional
+argument @samp{leaf} can be used to extend the signing to include leaf
+functions.
 
 @item -msve-vector-bits=@var{bits}
 @opindex msve-vector-bits
@@ -16241,6 +16247,10 @@  Values @samp{arc600}, @samp{arc601}, @samp{arc700} and
 @opindex multcost
 Replaced by @option{-mmultcost}.
 
+@item -msign-return-address=@var{scope}
+@opindex msign-return-address
+Replaced by @option{-mbranch-protection}
+
 @end table
 
 @node ARM Options
diff --git a/gcc/testsuite/gcc.target/aarch64/return_address_sign_1.c b/gcc/testsuite/gcc.target/aarch64/return_address_sign_1.c
index f87c3d28d1edff473a787a39a436e57076f97508..0140bee194f5a3ec53e794984c2f9b0e96bdbb63 100644
--- a/gcc/testsuite/gcc.target/aarch64/return_address_sign_1.c
+++ b/gcc/testsuite/gcc.target/aarch64/return_address_sign_1.c
@@ -1,6 +1,6 @@ 
 /* Testing return address signing where no combined instructions used.  */
 /* { dg-do compile } */
-/* { dg-options "-O2 -msign-return-address=all" } */
+/* { dg-options "-O2 -mbranch-protection=pac-ret+leaf" } */
 /* { dg-require-effective-target lp64 } */
 
 int foo (int);
diff --git a/gcc/testsuite/gcc.target/aarch64/return_address_sign_2.c b/gcc/testsuite/gcc.target/aarch64/return_address_sign_2.c
index c5c1439b92e6637f85c47c6161cd797c0d68df25..a4bc5b4533382d3d21085a763028576f72531ed7 100644
--- a/gcc/testsuite/gcc.target/aarch64/return_address_sign_2.c
+++ b/gcc/testsuite/gcc.target/aarch64/return_address_sign_2.c
@@ -1,6 +1,6 @@ 
 /* Testing return address signing where combined instructions used.  */
 /* { dg-do compile } */
-/* { dg-options "-O2 -msign-return-address=all" } */
+/* { dg-options "-O2 -mbranch-protection=pac-ret+leaf" } */
 /* { dg-require-effective-target lp64 } */
 
 int foo (int);
diff --git a/gcc/testsuite/gcc.target/aarch64/return_address_sign_3.c b/gcc/testsuite/gcc.target/aarch64/return_address_sign_3.c
index 7d9ec6eebd1ce452013d2895a551671c59e98f0c..e39ed34ab1c13d1368f4a625b4a466eb76354ef8 100644
--- a/gcc/testsuite/gcc.target/aarch64/return_address_sign_3.c
+++ b/gcc/testsuite/gcc.target/aarch64/return_address_sign_3.c
@@ -1,17 +1,17 @@ 
 /* Testing the disable of return address signing.  */
 /* { dg-do compile } */
-/* { dg-options "-O2 -msign-return-address=all" } */
+/* { dg-options "-O2 -mbranch-protection=pac-ret+leaf" } */
 /* { dg-require-effective-target lp64 } */
 
 int bar (int, int);
 
-int __attribute__ ((target ("arch=armv8.3-a, sign-return-address=non-leaf")))
+int __attribute__ ((target ("arch=armv8.3-a, branch-protection=pac-ret")))
 func1_leaf (int a, int b, int c, int d)
 {
   return a + b + c + d;
 }
 
-int __attribute__ ((target ("arch=armv8.3-a, sign-return-address=none")))
+int __attribute__ ((target ("arch=armv8.3-a, branch-protection=none")))
 func2_none (int a, int b, int c, int d)
 {
   return c + bar (a, b) + d;