mirror of git://gcc.gnu.org/git/gcc.git
[PATCH 2/3][GCC][AARCH64] Add new -mbranch-protection option to combine pointer signing and BTI
gcc/ChangeLog: 2019-01-08 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, 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: 2019-01-08 Sam Tebbs <sam.tebbs@arm.com> * gcc.target/aarch64/(return_address_sign_1.c, return_address_sign_2.c, 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. From-SVN: r267717
This commit is contained in:
parent
35724e5154
commit
efac62a3d1
|
|
@ -1,3 +1,26 @@
|
||||||
|
2019-01-08 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, 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.
|
||||||
|
|
||||||
2019-01-08 Alan Modra <amodra@gmail.com>
|
2019-01-08 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
PR target/88614
|
PR target/88614
|
||||||
|
|
|
||||||
|
|
@ -183,6 +183,12 @@ bool aarch64_pcrelative_literal_loads;
|
||||||
/* Global flag for whether frame pointer is enabled. */
|
/* Global flag for whether frame pointer is enabled. */
|
||||||
bool aarch64_use_frame_pointer;
|
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
|
/* Support for command line parsing of boolean flags in the tuning
|
||||||
structures. */
|
structures. */
|
||||||
struct aarch64_flag_desc
|
struct aarch64_flag_desc
|
||||||
|
|
@ -1170,6 +1176,79 @@ aarch64_cc;
|
||||||
|
|
||||||
#define AARCH64_INVERSE_CONDITION_CODE(X) ((aarch64_cc) (((int) X) ^ 1))
|
#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. */
|
/* The condition codes of the processor, and the inverse function. */
|
||||||
static const char * const aarch64_condition_codes[] =
|
static const char * const aarch64_condition_codes[] =
|
||||||
{
|
{
|
||||||
|
|
@ -11099,6 +11178,12 @@ aarch64_parse_override_string (const char* input_string,
|
||||||
static void
|
static void
|
||||||
aarch64_override_options_after_change_1 (struct gcc_options *opts)
|
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
|
/* PR 70044: We have to be careful about being called multiple times for the
|
||||||
same function. This means all changes should be repeatable. */
|
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;
|
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
|
/* Validate a command-line -march option. Parse the arch and extensions
|
||||||
(if any) specified in STR and throw errors if appropriate. Put the
|
(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
|
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_arch = NULL;
|
||||||
selected_tune = 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.
|
/* -mcpu=CPU is shorthand for -march=ARCH_FOR_CPU, -mtune=CPU.
|
||||||
If either of -march or -mtune is given, they override their
|
If either of -march or -mtune is given, they override their
|
||||||
respective component of -mcpu. */
|
respective component of -mcpu. */
|
||||||
|
|
@ -11690,6 +11882,8 @@ static void
|
||||||
aarch64_option_save (struct cl_target_option *ptr, struct gcc_options *opts)
|
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_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
|
/* 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;
|
opts->x_explicit_arch = ptr->x_explicit_arch;
|
||||||
selected_arch = aarch64_get_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_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);
|
aarch64_override_options_internal (opts);
|
||||||
}
|
}
|
||||||
|
|
@ -11897,6 +12098,37 @@ aarch64_handle_attr_cpu (const char *str)
|
||||||
return false;
|
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. */
|
/* Handle the argument STR to the tune= target attribute. */
|
||||||
|
|
||||||
static bool
|
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_ },
|
{ "cpu", aarch64_attr_custom, false, aarch64_handle_attr_cpu, OPT_mcpu_ },
|
||||||
{ "tune", aarch64_attr_custom, false, aarch64_handle_attr_tune,
|
{ "tune", aarch64_attr_custom, false, aarch64_handle_attr_tune,
|
||||||
OPT_mtune_ },
|
OPT_mtune_ },
|
||||||
|
{ "branch-protection", aarch64_attr_custom, false,
|
||||||
|
aarch64_handle_attr_branch_protection, OPT_mbranch_protection_ },
|
||||||
{ "sign-return-address", aarch64_attr_enum, false, NULL,
|
{ "sign-return-address", aarch64_attr_enum, false, NULL,
|
||||||
OPT_msign_return_address_ },
|
OPT_msign_return_address_ },
|
||||||
{ NULL, aarch64_attr_custom, false, NULL, OPT____ }
|
{ NULL, aarch64_attr_custom, false, NULL, OPT____ }
|
||||||
|
|
|
||||||
|
|
@ -149,8 +149,12 @@ mpc-relative-literal-loads
|
||||||
Target Report Save Var(pcrelative_literal_loads) Init(2) Save
|
Target Report Save Var(pcrelative_literal_loads) Init(2) Save
|
||||||
PC relative literal loads.
|
PC relative literal loads.
|
||||||
|
|
||||||
|
mbranch-protection=
|
||||||
|
Target RejectNegative Joined Var(aarch64_branch_protection_string) Save
|
||||||
|
Use branch-protection features.
|
||||||
|
|
||||||
msign-return-address=
|
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.
|
Select return address signing scope.
|
||||||
|
|
||||||
Enum
|
Enum
|
||||||
|
|
|
||||||
|
|
@ -631,6 +631,7 @@ Objective-C and Objective-C++ Dialects}.
|
||||||
-mlow-precision-recip-sqrt -mlow-precision-sqrt -mlow-precision-div @gol
|
-mlow-precision-recip-sqrt -mlow-precision-sqrt -mlow-precision-div @gol
|
||||||
-mpc-relative-literal-loads @gol
|
-mpc-relative-literal-loads @gol
|
||||||
-msign-return-address=@var{scope} @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
|
-march=@var{name} -mcpu=@var{name} -mtune=@var{name} @gol
|
||||||
-moverride=@var{string} -mverbose-cost-dump -mtrack-speculation}
|
-moverride=@var{string} -mverbose-cost-dump -mtrack-speculation}
|
||||||
|
|
||||||
|
|
@ -15738,7 +15739,21 @@ Select the function scope on which return address signing will be applied.
|
||||||
Permissible values are @samp{none}, which disables return address signing,
|
Permissible values are @samp{none}, which disables return address signing,
|
||||||
@samp{non-leaf}, which enables pointer signing for functions which are not leaf
|
@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
|
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}
|
@item -msve-vector-bits=@var{bits}
|
||||||
@opindex msve-vector-bits
|
@opindex msve-vector-bits
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,12 @@
|
||||||
|
2019-01-08 Sam Tebbs <sam.tebbs@arm.com>
|
||||||
|
|
||||||
|
* gcc.target/aarch64/(return_address_sign_1.c,
|
||||||
|
return_address_sign_2.c, 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.
|
||||||
|
|
||||||
2019-01-08 Paolo Carlini <paolo.carlini@oracle.com>
|
2019-01-08 Paolo Carlini <paolo.carlini@oracle.com>
|
||||||
|
|
||||||
* g++.dg/diagnostic/out-of-class-redeclaration.C: New.
|
* g++.dg/diagnostic/out-of-class-redeclaration.C: New.
|
||||||
|
|
|
||||||
|
|
@ -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" } } */
|
||||||
|
|
@ -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 } */
|
||||||
|
|
@ -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" } } */
|
||||||
|
|
@ -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 } */
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/* Testing return address signing where no combined instructions used. */
|
/* Testing return address signing where no combined instructions used. */
|
||||||
/* { dg-do compile } */
|
/* { dg-do compile } */
|
||||||
/* { dg-options "-O2 -msign-return-address=all" } */
|
/* { dg-options "-O2 -mbranch-protection=pac-ret+leaf" } */
|
||||||
/* { dg-require-effective-target lp64 } */
|
/* { dg-require-effective-target lp64 } */
|
||||||
|
|
||||||
int foo (int);
|
int foo (int);
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/* Testing return address signing where combined instructions used. */
|
/* Testing return address signing where combined instructions used. */
|
||||||
/* { dg-do compile } */
|
/* { dg-do compile } */
|
||||||
/* { dg-options "-O2 -msign-return-address=all" } */
|
/* { dg-options "-O2 -mbranch-protection=pac-ret+leaf" } */
|
||||||
/* { dg-require-effective-target lp64 } */
|
/* { dg-require-effective-target lp64 } */
|
||||||
|
|
||||||
int foo (int);
|
int foo (int);
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,17 @@
|
||||||
/* Testing the disable of return address signing. */
|
/* Testing the disable of return address signing. */
|
||||||
/* { dg-do compile } */
|
/* { dg-do compile } */
|
||||||
/* { dg-options "-O2 -msign-return-address=all" } */
|
/* { dg-options "-O2 -mbranch-protection=pac-ret+leaf" } */
|
||||||
/* { dg-require-effective-target lp64 } */
|
/* { dg-require-effective-target lp64 } */
|
||||||
|
|
||||||
int bar (int, int);
|
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)
|
func1_leaf (int a, int b, int c, int d)
|
||||||
{
|
{
|
||||||
return a + b + c + 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)
|
func2_none (int a, int b, int c, int d)
|
||||||
{
|
{
|
||||||
return c + bar (a, b) + d;
|
return c + bar (a, b) + d;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue