[3/8,Arm] Add option -mbranch-protection. [Was RE: [Patch 2/7, Arm, GCC] Add option -mbranch-protection.]

Message ID PAXPR08MB7075770D11A8F2AAB4CE9F1EEA869@PAXPR08MB7075.eurprd08.prod.outlook.com
State Superseded
Headers
Series [1/8,Arm,AArch64] Refactor mbranch-protection option parsing and make it common to AArch32 and AArch64 backends. [Was RE: [Patch 2/7, Arm, GCC] Add option -mbranch-protection.] |

Commit Message

Tejas Belagod Oct. 28, 2021, 11:42 a.m. UTC
  > -----Original Message-----
> From: Richard Earnshaw <Richard.Earnshaw@arm.com>
> Sent: Monday, October 11, 2021 1:58 PM
> To: Tejas Belagod <Tejas.Belagod@arm.com>; gcc-patches@gcc.gnu.org
> Subject: Re: [Patch 2/7, Arm, GCC] Add option -mbranch-protection.
> 
> On 08/10/2021 13:17, Tejas Belagod via Gcc-patches wrote:
> > Hi,
> >
> > Add -mbranch-protection option and its associated parsing routines.
> > This option enables the code-generation of pointer signing and
> > authentication instructions in function prologues and epilogues.
> >
> > Tested on arm-none-eabi. OK for trunk?
> >
> > 2021-10-04  Tejas Belagod  <tbelagod@arm.com>
> >
> > gcc/ChangeLog:
> >
> > 	* common/config/arm/arm-common.c
> > 	 (arm_print_hit_for_pacbti_option): New.
> > 	 (arm_progress_next_token): New.
> > 	 (arm_parse_pac_ret_clause): New routine for parsing the
> > 	pac-ret clause for -mbranch-protection.
> > 	(arm_parse_pacbti_option): New routine to parse all the options
> > 	to -mbranch-protection.
> > 	* config/arm/arm-protos.h (arm_parse_pacbti_option): Export.
> > 	* config/arm/arm.c (arm_configure)build_target): Handle option
> > 	to -mbranch-protection.
> > 	* config/arm/arm.opt (mbranch-protection). New.
> > 	(arm_enable_pacbti): New.
> >
> 
> You're missing documentation for invoke.texi.
> 
> Also, how does this differ from the exising option in aarch64?  Can the code
> from that be adapted to be made common to both targets rather than doing
> a new implementation?
> 
> Finally, there are far to many manifest constants in this patch, they need
> replacing with enums or #defines as appropriate if we cannot share the
> aarch64 code.

Thanks for the reviews.

Add -mbranch-protection option.  This option enables the code-generation of
pointer signing and authentication instructions in function prologues and
epilogues.

2021-10-25  Tejas Belagod  <tbelagod@arm.com>

gcc/ChangeLog:

	* config/arm/arm.c (arm_configure_build_target): Parse and validate
	-mbranch-protection option and initialize appropriate data structures.
	* config/arm/arm.opt: New option -mbranch-protection.
	* doc/invoke.texi: Document -mbranch-protection.

Tested the following configurations, OK for trunk?

-mthumb/-march=armv8.1-m.main+pacbti/-mfloat-abi=soft
-marm/-march=armv7-a/-mfpu=vfpv3-d16/-mfloat-abi=softfp
mcmodel=small and tiny
aarch64-none-linux-gnu native test and bootstrap
  

Comments

Richard Earnshaw Dec. 3, 2021, 3:55 p.m. UTC | #1
On 28/10/2021 12:42, Tejas Belagod via Gcc-patches wrote:
> 
> 
>> -----Original Message-----
>> From: Richard Earnshaw <Richard.Earnshaw@arm.com>
>> Sent: Monday, October 11, 2021 1:58 PM
>> To: Tejas Belagod <Tejas.Belagod@arm.com>; gcc-patches@gcc.gnu.org
>> Subject: Re: [Patch 2/7, Arm, GCC] Add option -mbranch-protection.
>>
>> On 08/10/2021 13:17, Tejas Belagod via Gcc-patches wrote:
>>> Hi,
>>>
>>> Add -mbranch-protection option and its associated parsing routines.
>>> This option enables the code-generation of pointer signing and
>>> authentication instructions in function prologues and epilogues.
>>>
>>> Tested on arm-none-eabi. OK for trunk?
>>>
>>> 2021-10-04  Tejas Belagod  <tbelagod@arm.com>
>>>
>>> gcc/ChangeLog:
>>>
>>> 	* common/config/arm/arm-common.c
>>> 	 (arm_print_hit_for_pacbti_option): New.
>>> 	 (arm_progress_next_token): New.
>>> 	 (arm_parse_pac_ret_clause): New routine for parsing the
>>> 	pac-ret clause for -mbranch-protection.
>>> 	(arm_parse_pacbti_option): New routine to parse all the options
>>> 	to -mbranch-protection.
>>> 	* config/arm/arm-protos.h (arm_parse_pacbti_option): Export.
>>> 	* config/arm/arm.c (arm_configure)build_target): Handle option
>>> 	to -mbranch-protection.
>>> 	* config/arm/arm.opt (mbranch-protection). New.
>>> 	(arm_enable_pacbti): New.
>>>
>>
>> You're missing documentation for invoke.texi.
>>
>> Also, how does this differ from the exising option in aarch64?  Can the code
>> from that be adapted to be made common to both targets rather than doing
>> a new implementation?
>>
>> Finally, there are far to many manifest constants in this patch, they need
>> replacing with enums or #defines as appropriate if we cannot share the
>> aarch64 code.
> 
> Thanks for the reviews.
> 
> Add -mbranch-protection option.  This option enables the code-generation of
> pointer signing and authentication instructions in function prologues and
> epilogues.
> 
> 2021-10-25  Tejas Belagod  <tbelagod@arm.com>
> 
> gcc/ChangeLog:
> 
> 	* config/arm/arm.c (arm_configure_build_target): Parse and validate
> 	-mbranch-protection option and initialize appropriate data structures.
> 	* config/arm/arm.opt: New option -mbranch-protection.

.../arm.opt (-mbranch-protection) : New option.

> 	* doc/invoke.texi: Document -mbranch-protection.

.../invoke.texi (Arm Options): Document it.

> 
> Tested the following configurations, OK for trunk?
> 
> -mthumb/-march=armv8.1-m.main+pacbti/-mfloat-abi=soft
> -marm/-march=armv7-a/-mfpu=vfpv3-d16/-mfloat-abi=softfp
> mcmodel=small and tiny
> aarch64-none-linux-gnu native test and bootstrap
> 

+@item 
-mbranch-protection=@var{none}|@var{standard}|@var{pac-ret}[+@var{leaf}][+@var{bti}]|@var{bti}[+@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).  The optional argument 
@samp{leaf}
+can be used to extend the signing to include leaf functions.
+@samp{bti} turns on branch target identification mechanism.

This doesn't really use the right documentation style.  Closer would be:

===============
@item 
-mbranch-protection=@var{none}|@var{standard}|@var{pac-ret}[+@var{leaf}][+@var{bti}]|@var{bti}[+@var{pac-ret}[+@var{leaf}]]
@opindex mbranch-protection
Enable branch protection features (armv8.1-m.main only).
@samp{none} generate code without branch protection or return address 
signing.
@samp{standard[+@var{leaf}]} generate code with all branch protection 
features enabled at their standard level.
@samp{pac-ret[+@var{leaf}]} generate code with return address signing 
set to its standard level, which is to sign all functions that save the 
return address to memory.
@samp{leaf} When return address signing is enabled, also sign leaf 
functions even if they do not write the return address to memory.
+@samp{bti} Add landing-pad instructions at the permitted targets of 
indirect branch instructions.

If the @samp{+pacbti} architecture extension is not enabled, then all 
branch protection and return address signing operations are constrained 
to use only the instructions defined in the architectural-NOP space. 
The generated code will remain backwards-compatible with earlier 
versions of the architecture, but the additional security can be enabled 
at run time on processors that support the @samp{PACBTI} extension.

Branch target enforcement using BTI can only be enabled at runtime if 
all code in the application has been compiled with at least 
@samp{-mbranch-protection=bti}.

The default is to generate code without branch protection or return 
address signing.
================

R.
  
Andrea Corallo Dec. 6, 2021, 2:47 p.m. UTC | #2
Richard Earnshaw via Gcc-patches <gcc-patches@gcc.gnu.org> writes:

[...]

>> Thanks for the reviews.
>> Add -mbranch-protection option.  This option enables the
>> code-generation of
>> pointer signing and authentication instructions in function prologues and
>> epilogues.
>> 2021-10-25  Tejas Belagod  <tbelagod@arm.com>
>> gcc/ChangeLog:
>> 	* config/arm/arm.c (arm_configure_build_target): Parse and
>> validate
>> 	-mbranch-protection option and initialize appropriate data structures.
>> 	* config/arm/arm.opt: New option -mbranch-protection.
>
> .../arm.opt (-mbranch-protection) : New option.
>
>> 	* doc/invoke.texi: Document -mbranch-protection.
>
> .../invoke.texi (Arm Options): Document it.
>
>> Tested the following configurations, OK for trunk?
>> -mthumb/-march=armv8.1-m.main+pacbti/-mfloat-abi=soft
>> -marm/-march=armv7-a/-mfpu=vfpv3-d16/-mfloat-abi=softfp
>> mcmodel=small and tiny
>> aarch64-none-linux-gnu native test and bootstrap
>> 
>
> +@item
> -mbranch-protection=@var{none}|@var{standard}|@var{pac-ret}[+@var{leaf}][+@var{bti}]|@var{bti}[+@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).  The optional argument
> @samp{leaf}
> +can be used to extend the signing to include leaf functions.
> +@samp{bti} turns on branch target identification mechanism.
>
> This doesn't really use the right documentation style.  Closer would be:

[...]

Hi Richard,

thanks for reviewing, here is the updated patch.

Best Regards

  Andrea
From 3383a1e265b7b695c5d6ce6115ad66eed2a4cb48 Mon Sep 17 00:00:00 2001
From: Andrea Corallo <andrea.corallo@arm.com>
Date: Mon, 6 Dec 2021 11:39:03 +0100
Subject: [PATCH] Add option -mbranch-protection.

Add -mbranch-protection option.  This option enables the
code-generation of pointer signing and authentication instructions in
function prologues and epilogues.

gcc/ChangeLog:

	* config/arm/arm.c (arm_configure_build_target): Parse and validate
	-mbranch-protection option and initialize appropriate data structures.
	* config/arm/arm.opt (-mbranch-protection): New option.
	* doc/invoke.texi (Arm Options): Document it.

Co-Authored-By: Tejas Belagod  <tbelagod@arm.com>
Co-Authored-By: Richard Earnshaw <Richard.Earnshaw@arm.com>
---
 gcc/config/arm/arm.c   | 11 +++++++++++
 gcc/config/arm/arm.opt |  4 ++++
 gcc/doc/invoke.texi    | 35 +++++++++++++++++++++++++++++++++--
 3 files changed, 48 insertions(+), 2 deletions(-)

diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 96186b8ad02..ee22acddee5 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -3237,6 +3237,17 @@ arm_configure_build_target (struct arm_build_target *target,
       tune_opts = strchr (opts->x_arm_tune_string, '+');
     }
 
+  if (opts->x_arm_branch_protection_string)
+    {
+      aarch_validate_mbranch_protection (opts->x_arm_branch_protection_string);
+
+      if (aarch_ra_sign_key != AARCH_KEY_A)
+	{
+	  warning (0, "invalid key type for %<-mbranch-protection=%>");
+	  aarch_ra_sign_key = AARCH_KEY_A;
+	}
+    }
+
   if (arm_selected_arch)
     {
       arm_initialize_isa (target->isa, arm_selected_arch->common.isa_bits);
diff --git a/gcc/config/arm/arm.opt b/gcc/config/arm/arm.opt
index 5c5b4f3ae06..4f2754c3e84 100644
--- a/gcc/config/arm/arm.opt
+++ b/gcc/config/arm/arm.opt
@@ -313,6 +313,10 @@ mbranch-cost=
 Target RejectNegative Joined UInteger Var(arm_branch_cost) Init(-1)
 Cost to assume for a branch insn.
 
+mbranch-protection=
+Target RejectNegative Joined Var(arm_branch_protection_string) Save
+Use branch-protection features.
+
 mgeneral-regs-only
 Target RejectNegative Mask(GENERAL_REGS_ONLY) Save
 Generate code which uses the core registers only (r0-r14).
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 3257df5596d..a808c6bb599 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -820,7 +820,9 @@ Objective-C and Objective-C++ Dialects}.
 -mpure-code @gol
 -mcmse @gol
 -mfix-cmse-cve-2021-35465 @gol
--mfdpic}
+-mfdpic @gol
+-mbranch-protection=@var{none}|@var{standard}|@var{pac-ret}[+@var{leaf}]
+[+@var{bti}]|@var{bti}[+@var{pac-ret}[+@var{leaf}]]}
 
 @emph{AVR Options}
 @gccoptlist{-mmcu=@var{mcu}  -mabsdata  -maccumulate-args @gol
@@ -21187,7 +21189,36 @@ The opposite @option{-mno-fdpic} option is useful (and required) to
 build the Linux kernel using the same (@code{arm-*-uclinuxfdpiceabi})
 toolchain as the one used to build the userland programs.
 
-@end table
+@item
+-mbranch-protection=@var{none}|@var{standard}|@var{pac-ret}[+@var{leaf}][+@var{bti}]|@var{bti}[+@var{pac-ret}[+@var{leaf}]]
+@opindex mbranch-protection
+Enable branch protection features (armv8.1-m.main only).
+@samp{none} generate code without branch protection or return address
+signing.
+@samp{standard[+@var{leaf}]} generate code with all branch protection
+features enabled at their standard level.
+@samp{pac-ret[+@var{leaf}]} generate code with return address signing
+set to its standard level, which is to sign all functions that save
+the return address to memory.
+@samp{leaf} When return address signing is enabled, also sign leaf
+functions even if they do not write the return address to memory.
++@samp{bti} Add landing-pad instructions at the permitted targets of
+indirect branch instructions.
+
+If the @samp{+pacbti} architecture extension is not enabled, then all
+branch protection and return address signing operations are
+constrained to use only the instructions defined in the
+architectural-NOP space. The generated code will remain
+backwards-compatible with earlier versions of the architecture, but
+the additional security can be enabled at run time on processors that
+support the @samp{PACBTI} extension.
+
+Branch target enforcement using BTI can only be enabled at runtime if
+all code in the application has been compiled with at least
+@samp{-mbranch-protection=bti}.
+
+The default is to generate code without branch protection or return
+address signing.
 
 @node AVR Options
 @subsection AVR Options
  

Patch

diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index a952655db80663f28f5a5d12005f2adb4702894f..946841526ee127105396097d143e755bdfc756f5 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -3216,6 +3216,17 @@  arm_configure_build_target (struct arm_build_target *target,
       tune_opts = strchr (opts->x_arm_tune_string, '+');
     }
 
+  if (opts->x_arm_branch_protection_string)
+    {
+      aarch_validate_mbranch_protection (opts->x_arm_branch_protection_string);
+
+      if (aarch_ra_sign_key != AARCH_KEY_A)
+	{
+	  warning (0, "invalid key type for %<-mbranch-protection=%>");
+	  aarch_ra_sign_key = AARCH_KEY_A;
+	}
+    }
+
   if (arm_selected_arch)
     {
       arm_initialize_isa (target->isa, arm_selected_arch->common.isa_bits);
diff --git a/gcc/config/arm/arm.opt b/gcc/config/arm/arm.opt
index 5c5b4f3ae0699a3a9d78df40a5ab65324dcba7b9..4f2754c3e84c436f7058ea0bd1c9f517b3a63ccd 100644
--- a/gcc/config/arm/arm.opt
+++ b/gcc/config/arm/arm.opt
@@ -313,6 +313,10 @@  mbranch-cost=
 Target RejectNegative Joined UInteger Var(arm_branch_cost) Init(-1)
 Cost to assume for a branch insn.
 
+mbranch-protection=
+Target RejectNegative Joined Var(arm_branch_protection_string) Save
+Use branch-protection features.
+
 mgeneral-regs-only
 Target RejectNegative Mask(GENERAL_REGS_ONLY) Save
 Generate code which uses the core registers only (r0-r14).
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 27df8cf5bee79c2abac8b81c1ac54f1c3e50c628..7f886db008a39c44819616eb2799c01822d0aae9 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -810,7 +810,9 @@  Objective-C and Objective-C++ Dialects}.
 -mpure-code @gol
 -mcmse @gol
 -mfix-cmse-cve-2021-35465 @gol
--mfdpic}
+-mfdpic @gol
+-mbranch-protection=@var{none}|@var{standard}|@var{pac-ret}[+@var{leaf}]
+[+@var{bti}]|@var{bti}[+@var{pac-ret}[+@var{leaf}]]}
 
 @emph{AVR Options}
 @gccoptlist{-mmcu=@var{mcu}  -mabsdata  -maccumulate-args @gol
@@ -20969,6 +20971,18 @@  The opposite @option{-mno-fdpic} option is useful (and required) to
 build the Linux kernel using the same (@code{arm-*-uclinuxfdpiceabi})
 toolchain as the one used to build the userland programs.
 
+@item -mbranch-protection=@var{none}|@var{standard}|@var{pac-ret}[+@var{leaf}][+@var{bti}]|@var{bti}[+@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).  The optional argument @samp{leaf}
+can be used to extend the signing to include leaf functions.
+@samp{bti} turns on branch target identification mechanism.
 @end table
 
 @node AVR Options