public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Sam Tebbs <Sam.Tebbs@arm.com>
To: "gcc-patches@gcc.gnu.org" <gcc-patches@gcc.gnu.org>
Cc: Richard Earnshaw <Richard.Earnshaw@arm.com>,
	Marcus Shawcroft	<Marcus.Shawcroft@arm.com>,
	James Greenhalgh <James.Greenhalgh@arm.com>, nd	<nd@arm.com>
Subject: Re: [PATCH 3/3][GCC][AARCH64] Add support for pointer authentication B key
Date: Fri, 21 Dec 2018 15:04:00 -0000	[thread overview]
Message-ID: <f284bc8a-8bca-feb5-2d90-deced94cef20@arm.com> (raw)
In-Reply-To: <e0a467c8-f219-a8d7-db41-999b9659cf8d@arm.com>

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

On 11/9/18 11:04 AM, Sam Tebbs wrote:
> On 11/02/2018 06:01 PM, Sam Tebbs wrote:
>
>> On 11/02/2018 05:35 PM, Sam Tebbs wrote:
>>
>>> Hi all,
>>>
>>> This patch adds support for the Armv8.3-A pointer authentication instructions
>>> that use the B-key (pacib*, autib* and retab). This required adding builtins for
>>> pacib1716 and autib1716, adding the "b-key" feature to the -mbranch-protection
>>> option, and required emitting a new CFI directive ".cfi_b_key_frame" which
>>> causes GAS to add 'B' to the CIE augmentation string. I also had to add a new
>>> hook called ASM_POST_CFI_STARTPROC which is triggered when the .cfi_startproc
>>> directive is emitted.
>>>
>>> The libgcc stack unwinder has been amended to authenticate return addresses
>>> with the B key when the function has been signed with the B key.
>>>
>>> The previous patch in this series is here:
>>> https://gcc.gnu.org/ml/gcc-patches/2018-11/msg00104.html
>>>
>>> Bootstrapped successfully and regression tested on aarch64-none-elf.
>>>
>>> OK for trunk?
>>>
>>> gcc/
>>> 2018-11-02  Sam Tebbs  <sam.tebbs@arm.com>
>>>
>>> 	* config/aarch64/aarch64-builtins.c (aarch64_builtins): Add
>>> 	AARCH64_PAUTH_BUILTIN_AUTIB1716 and AARCH64_PAUTH_BUILTIN_PACIB1716.
>>> 	* config/aarch64/aarch64-builtins.c (aarch64_init_pauth_hint_builtins):
>>> 	Add autib1716 and pacib1716 initialisation.
>>> 	* config/aarch64/aarch64-builtins.c (aarch64_expand_builtin): Add checks
>>> 	for autib1716 and pacib1716.
>>> 	* config/aarch64/aarch64-protos.h (aarch64_key_type,
>>> 	aarch64_post_cfi_startproc): Define.
>>> 	* config/aarch64/aarch64-protos.h (aarch64_ra_sign_key): Define extern.
>>> 	* config/aarch64/aarch64.c (aarch64_return_address_signing_enabled): Add
>>> 	check for b-key, remove frame.laid_out assertion.
>>> 	* config/aarch64/aarch64.c (aarch64_ra_sign_key,
>>> 	aarch64_post_cfi_startproc, aarch64_handle_pac_ret_b_key): Define.
>>> 	* config/aarch64/aarch64.h (TARGET_ASM_POST_CFI_STARTPROC): Define.
>>> 	* config/aarch64/aarch64.c (aarch64_pac_ret_subtypes): Add "b-key".
>>> 	* config/aarch64/aarch64.md (unspec): Add UNSPEC_AUTIA1716,
>>> 	UNSPEC_AUTIB1716, UNSPEC_AUTIASP, UNSPEC_AUTIBSP, UNSPEC_PACIA1716,
>>> 	UNSPEC_PACIB1716, UNSPEC_PACIASP, UNSPEC_PACIBSP.
>>> 	* config/aarch64/aarch64.md (do_return): Add check for b-key.
>>> 	* config/aarch64/aarch64.md (<pauth_mnem_prefix>sp): Add check for
>>> 	signing key and scope selected.
>>> 	* config/aarch64/aarch64.md (<pauth_mnem_prefix>1716): Add check for
>>> 	signing key and scope selected.
>>> 	* config/aarch64/aarch64.opt (msign-return-address=): Deprecate.
>>> 	* config/aarch64/iterators.md (PAUTH_LR_SP): Add UNSPEC_AUTIASP,
>>> 	UNSPEC_AUTIBSP, UNSPEC_PACIASP, UNSPEC_PACIBSP.
>>> 	* config/aarch64/iterators.md (PAUTH_17_16): Add UNSPEC_AUTIA1716,
>>> 	UNSPEC_AUTIB1716, UNSPEC_PACIA1716, UNSPEC_PACIB1716.
>>> 	* config/aarch64/iterators.md (pauth_mnem_prefix): Add UNSPEC_AUTIA1716,
>>> 	UNSPEC_AUTIB1716, UNSPEC_PACIA1716, UNSPEC_PACIB1716, UNSPEC_AUTIASP,
>>> 	UNSPEC_AUTIBSP, UNSPEC_PACIASP, UNSPEC_PACIBSP.
>>> 	* config/aarch64/iterators.md (pauth_hint_num_a): Replace
>>> 	UNSPEC_PACI1716 and UNSPEC_AUTI1716 with UNSPEC_PACIA1716 and
>>> 	UNSPEC_AUTIA1716 respectively.
>>> 	* config/aarch64/iterators.md (pauth_hint_num_b): New int attribute.
>>>
>>> gcc/testsuite
>>> 2018-11-02  Sam Tebbs  <sam.tebbs@arm.com>
>>>
>>> 	* gcc.target/aarch64/return_address_sign_1.c (dg-final): Replace
>>> 	"autiasp" and "paciasp" with "hint\t29 // autisp" and
>>> 	"hint\t25 // pacisp" respectively.
>>> 	* gcc.target/aarch64/return_address_sign_2.c (dg-final): Replace
>>> 	"paciasp" with "hint\t25 // pacisp".
>>> 	* gcc.target/aarch64/return_address_sign_3.c (dg-final): Replace
>>> 	"paciasp" and "autiasp" with "pacisp" and "autisp" respectively.
>>> 	* gcc.target/aarch64/return_address_sign_b_1.c: New file.
>>> 	* gcc.target/aarch64/return_address_sign_b_2.c: New file.
>>> 	* gcc.target/aarch64/return_address_sign_b_3.c: New file.
>>> 	* gcc.target/aarch64/return_address_sign_b_exception.c: New file.
>>> 	* gcc.target/aarch64/return_address_sign_builtin.c: New file
>>>
>>> libgcc/
>>> 2018-11-02  Sam Tebbs  <sam.tebbs@arm.com>
>>>
>>> 	* config/aarch64/aarch64-unwind.h (aarch64_cie_signed_with_b_key): New
>>> 	function.
>>> 	* config/aarch64/aarch64-unwind.h (aarch64_post_extract_frame_addr,
>>> 	aarch64_post_frob_eh_handler_addr): Add	check for b-key.
>>> 	* unwind-dw2-fde.c (get_cie_encoding): Add check for 'B' in augmentation
>>> 	string.
>>> 	* unwind-dw2.c (extract_cie_info): Add check for 'B' in augmentation
>>> 	string.
>> Attached is an updated patch rebased on an improvement to the
>> -mbranch-protection option documentation.
> ping

Attached is an improved patch with "hint" removed from the test scans, 
pauth_hint_num_a and pauth_hint_num_b merged into pauth_hint_num and the 
"gcc_assert (cfun->machine->frame.laid_out)" removal reverted since was 
an unnecessary change.

OK for trunk?

gcc/
2018-12-21  Sam Tebbs<sam.tebbs@arm.com>

	* config/aarch64/aarch64-builtins.c (aarch64_builtins): Add
	AARCH64_PAUTH_BUILTIN_AUTIB1716 and AARCH64_PAUTH_BUILTIN_PACIB1716.
	* config/aarch64/aarch64-builtins.c (aarch64_init_pauth_hint_builtins):
	Add autib1716 and pacib1716 initialisation.
	* config/aarch64/aarch64-builtins.c (aarch64_expand_builtin): Add checks
	for autib1716 and pacib1716.
	* config/aarch64/aarch64-protos.h (aarch64_key_type,
	aarch64_post_cfi_startproc): Define.
	* config/aarch64/aarch64-protos.h (aarch64_ra_sign_key): Define extern.
	* config/aarch64/aarch64.c (aarch64_return_address_signing_enabled): Add
	check for b-key.
	* config/aarch64/aarch64.c (aarch64_ra_sign_key,
	aarch64_post_cfi_startproc, aarch64_handle_pac_ret_b_key): Define.
	* config/aarch64/aarch64.h (TARGET_ASM_POST_CFI_STARTPROC): Define.
	* config/aarch64/aarch64.c (aarch64_pac_ret_subtypes): Add "b-key".
	* config/aarch64/aarch64.md (unspec): Add UNSPEC_AUTIA1716,
	UNSPEC_AUTIB1716, UNSPEC_AUTIASP, UNSPEC_AUTIBSP, UNSPEC_PACIA1716,
	UNSPEC_PACIB1716, UNSPEC_PACIASP, UNSPEC_PACIBSP.
	* config/aarch64/aarch64.md (do_return): Add check for b-key.
	* config/aarch64/aarch64.md (<pauth_mnem_prefix>sp): Replace
	pauth_hint_num_a with pauth_hint_num.
	* config/aarch64/aarch64.md (<pauth_mnem_prefix>1716): Replace
	pauth_hint_num_a with pauth_hint_num.
	* config/aarch64/aarch64.opt (msign-return-address=): Deprecate.
	* config/aarch64/iterators.md (PAUTH_LR_SP): Add UNSPEC_AUTIASP,
	UNSPEC_AUTIBSP, UNSPEC_PACIASP, UNSPEC_PACIBSP.
	* config/aarch64/iterators.md (PAUTH_17_16): Add UNSPEC_AUTIA1716,
	UNSPEC_AUTIB1716, UNSPEC_PACIA1716, UNSPEC_PACIB1716.
	* config/aarch64/iterators.md (pauth_mnem_prefix): Add UNSPEC_AUTIA1716,
	UNSPEC_AUTIB1716, UNSPEC_PACIA1716, UNSPEC_PACIB1716, UNSPEC_AUTIASP,
	UNSPEC_AUTIBSP, UNSPEC_PACIASP, UNSPEC_PACIBSP.
	* config/aarch64/iterators.md (pauth_hint_num_a): Replace
	UNSPEC_PACI1716 and UNSPEC_AUTI1716 with UNSPEC_PACIA1716 and
	UNSPEC_AUTIA1716 respectively.
	* config/aarch64/iterators.md (pauth_hint_num_a): Rename to pauth_hint_num
	and add UNSPEC_PACIBSP, UNSPEC_AUTIBSP, UNSPEC_PACIB1716, UNSPEC_AUTIB1716.

gcc/testsuite
2018-12-21  Sam Tebbs<sam.tebbs@arm.com>

	* gcc.target/aarch64/return_address_sign_1.c (dg-final): Replace
	"autiasp" and "paciasp" with "hint\t29 // autisp" and
	"hint\t25 // pacisp" respectively.
	* gcc.target/aarch64/return_address_sign_2.c (dg-final): Replace
	"paciasp" with "hint\t25 // pacisp".
	* gcc.target/aarch64/return_address_sign_3.c (dg-final): Replace
	"paciasp" and "autiasp" with "pacisp" and "autisp" respectively.
	* gcc.target/aarch64/return_address_sign_b_1.c: New file.
	* gcc.target/aarch64/return_address_sign_b_2.c: New file.
	* gcc.target/aarch64/return_address_sign_b_3.c: New file.
	* gcc.target/aarch64/return_address_sign_b_exception.c: New file.
	* gcc.target/aarch64/return_address_sign_builtin.c: New file

libgcc/
2018-12-21  Sam Tebbs<sam.tebbs@arm.com>

	* config/aarch64/aarch64-unwind.h (aarch64_cie_signed_with_b_key): New
	function.
	* config/aarch64/aarch64-unwind.h (aarch64_post_extract_frame_addr,
	aarch64_post_frob_eh_handler_addr): Add	check for b-key.
	* unwind-dw2-fde.c (get_cie_encoding): Add check for 'B' in augmentation
	string.
	* unwind-dw2.c (extract_cie_info): Add check for 'B' in augmentation
	string.


[-- Attachment #2: diff --]
[-- Type: text/plain, Size: 24431 bytes --]

diff --git a/gcc/config/aarch64/aarch64-builtins.c b/gcc/config/aarch64/aarch64-builtins.c
index 8cced94567008e28b1761ec8771589a3925f2904..d676f36c157c486cc9cbe6bffe0a7389ba0ccdd8 100644
--- a/gcc/config/aarch64/aarch64-builtins.c
+++ b/gcc/config/aarch64/aarch64-builtins.c
@@ -398,6 +398,8 @@ enum aarch64_builtins
   /* ARMv8.3-A Pointer Authentication Builtins.  */
   AARCH64_PAUTH_BUILTIN_AUTIA1716,
   AARCH64_PAUTH_BUILTIN_PACIA1716,
+  AARCH64_PAUTH_BUILTIN_AUTIB1716,
+  AARCH64_PAUTH_BUILTIN_PACIB1716,
   AARCH64_PAUTH_BUILTIN_XPACLRI,
   AARCH64_BUILTIN_MAX
 };
@@ -971,6 +973,14 @@ aarch64_init_pauth_hint_builtins (void)
     = add_builtin_function ("__builtin_aarch64_pacia1716", ftype_pointer_auth,
 			    AARCH64_PAUTH_BUILTIN_PACIA1716, BUILT_IN_MD, NULL,
 			    NULL_TREE);
+  aarch64_builtin_decls[AARCH64_PAUTH_BUILTIN_AUTIB1716]
+    = add_builtin_function ("__builtin_aarch64_autib1716", ftype_pointer_auth,
+			    AARCH64_PAUTH_BUILTIN_AUTIB1716, BUILT_IN_MD, NULL,
+			    NULL_TREE);
+  aarch64_builtin_decls[AARCH64_PAUTH_BUILTIN_PACIB1716]
+    = add_builtin_function ("__builtin_aarch64_pacib1716", ftype_pointer_auth,
+			    AARCH64_PAUTH_BUILTIN_PACIB1716, BUILT_IN_MD, NULL,
+			    NULL_TREE);
   aarch64_builtin_decls[AARCH64_PAUTH_BUILTIN_XPACLRI]
     = add_builtin_function ("__builtin_aarch64_xpaclri", ftype_pointer_strip,
 			    AARCH64_PAUTH_BUILTIN_XPACLRI, BUILT_IN_MD, NULL,
@@ -1360,6 +1370,8 @@ aarch64_expand_builtin (tree exp,
 
     case AARCH64_PAUTH_BUILTIN_AUTIA1716:
     case AARCH64_PAUTH_BUILTIN_PACIA1716:
+    case AARCH64_PAUTH_BUILTIN_AUTIB1716:
+    case AARCH64_PAUTH_BUILTIN_PACIB1716:
     case AARCH64_PAUTH_BUILTIN_XPACLRI:
       arg0 = CALL_EXPR_ARG (exp, 0);
       op0 = force_reg (Pmode, expand_normal (arg0));
@@ -1383,8 +1395,24 @@ aarch64_expand_builtin (tree exp,
 	{
 	  tree arg1 = CALL_EXPR_ARG (exp, 1);
 	  rtx op1 = force_reg (Pmode, expand_normal (arg1));
-	  icode = (fcode == AARCH64_PAUTH_BUILTIN_PACIA1716
-		   ? CODE_FOR_paci1716 : CODE_FOR_auti1716);
+	  switch (fcode)
+	    {
+	    case AARCH64_PAUTH_BUILTIN_AUTIA1716:
+	      icode = CODE_FOR_autia1716;
+	      break;
+	    case AARCH64_PAUTH_BUILTIN_AUTIB1716:
+	      icode = CODE_FOR_autib1716;
+	      break;
+	    case AARCH64_PAUTH_BUILTIN_PACIA1716:
+	      icode = CODE_FOR_pacia1716;
+	      break;
+	    case AARCH64_PAUTH_BUILTIN_PACIB1716:
+	      icode = CODE_FOR_pacib1716;
+	      break;
+	    default:
+	      icode = 0;
+	      gcc_unreachable ();
+	    }
 
 	  rtx x16_reg = gen_rtx_REG (Pmode, R16_REGNUM);
 	  rtx x17_reg = gen_rtx_REG (Pmode, R17_REGNUM);
diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h
index e64768aadead2901c1168b3c2ec82c17052ff807..7eec71e15accead4f14b66e674535af52840c2ab 100644
--- a/gcc/config/aarch64/aarch64-protos.h
+++ b/gcc/config/aarch64/aarch64-protos.h
@@ -396,8 +396,17 @@ enum simd_immediate_check {
   AARCH64_CHECK_MOV  = AARCH64_CHECK_ORR | AARCH64_CHECK_BIC
 };
 
+/* The key type that -msign-return-address should use.  */
+enum aarch64_key_type {
+  AARCH64_KEY_A,
+  AARCH64_KEY_B
+};
+
+extern enum aarch64_key_type aarch64_ra_sign_key;
+
 extern struct tune_params aarch64_tune_params;
 
+void aarch64_post_cfi_startproc (void);
 poly_int64 aarch64_initial_elimination_offset (unsigned, unsigned);
 int aarch64_get_condition_code (rtx);
 bool aarch64_address_valid_for_prefetch_p (rtx, bool);
diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h
index 8b5b2ab0bdb0e37d8a3fc2278715d3c8f5adbddb..575a40d836f99f54ffc3725208cef6af1639089a 100644
--- a/gcc/config/aarch64/aarch64.h
+++ b/gcc/config/aarch64/aarch64.h
@@ -483,6 +483,9 @@ extern unsigned aarch64_architecture_version;
 #define ASM_DECLARE_FUNCTION_NAME(STR, NAME, DECL)	\
   aarch64_declare_function_name (STR, NAME, DECL)
 
+/* Output assembly strings after .cfi_startproc is emitted.  */
+#define ASM_POST_CFI_STARTPROC  aarch64_post_cfi_startproc
+
 /* For EH returns X4 contains the stack adjustment.  */
 #define EH_RETURN_STACKADJ_RTX	gen_rtx_REG (Pmode, R4_REGNUM)
 #define EH_RETURN_HANDLER_RTX  aarch64_eh_return_handler_rtx ()
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 784c93a8e9701a671004e3dfda463d726611c340..4a8a9e5a30e57c0b4c9728f59aab695b48aa7279 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -1144,6 +1144,8 @@ static const struct processor *selected_arch;
 static const struct processor *selected_cpu;
 static const struct processor *selected_tune;
 
+enum aarch64_key_type aarch64_ra_sign_key = AARCH64_KEY_A;
+
 /* The current tuning set.  */
 struct tune_params aarch64_tune_params = generic_tunings;
 
@@ -1212,6 +1214,7 @@ static enum aarch64_parse_opt_result
 aarch64_handle_standard_branch_protection (char* str, char* rest)
 {
   aarch64_ra_sign_scope = AARCH64_FUNCTION_NON_LEAF;
+  aarch64_ra_sign_key = AARCH64_KEY_A;
   if (rest)
     {
       error ("unexpected %<%s%> after %<%s%>", rest, str);
@@ -1225,6 +1228,7 @@ aarch64_handle_pac_ret_protection (char* str ATTRIBUTE_UNUSED,
 				    char* rest ATTRIBUTE_UNUSED)
 {
   aarch64_ra_sign_scope = AARCH64_FUNCTION_NON_LEAF;
+  aarch64_ra_sign_key = AARCH64_KEY_A;
   return AARCH64_PARSE_OK;
 }
 
@@ -1236,8 +1240,17 @@ aarch64_handle_pac_ret_leaf (char* str ATTRIBUTE_UNUSED,
   return AARCH64_PARSE_OK;
 }
 
-static const struct aarch64_branch_protect_type aarch64_pac_ret_subtypes[] = {
+static enum aarch64_parse_opt_result
+aarch64_handle_pac_ret_b_key (char* str ATTRIBUTE_UNUSED,
+			      char* rest ATTRIBUTE_UNUSED)
+{
+  aarch64_ra_sign_key = AARCH64_KEY_B;
+  return AARCH64_PARSE_OK;
+}
+
+static const struct aarch64_branch_protec_type aarch64_pac_ret_subtypes[] = {
   { "leaf", aarch64_handle_pac_ret_leaf, NULL, 0 },
+  { "b-key", aarch64_handle_pac_ret_b_key, NULL, 0 },
   { NULL, NULL, NULL, 0 }
 };
 
@@ -4719,7 +4732,7 @@ aarch64_return_address_signing_enabled (void)
   gcc_assert (cfun->machine->frame.laid_out);
 
   /* If signing scope is AARCH64_FUNCTION_NON_LEAF, we only sign a leaf function
-     if it's LR is pushed onto stack.  */
+     if its LR is pushed onto stack.  */
   return (aarch64_ra_sign_scope == AARCH64_FUNCTION_ALL
 	  || (aarch64_ra_sign_scope == AARCH64_FUNCTION_NON_LEAF
 	      && cfun->machine->frame.reg_offset[LR_REGNUM] >= 0));
@@ -5499,7 +5512,17 @@ aarch64_expand_prologue (void)
   /* Sign return address for functions.  */
   if (aarch64_return_address_signing_enabled ())
     {
-      insn = emit_insn (gen_pacisp ());
+      switch (aarch64_ra_sign_key)
+	{
+	  case AARCH64_KEY_A:
+	    insn = emit_insn (gen_paciasp ());
+	    break;
+	  case AARCH64_KEY_B:
+	    insn = emit_insn (gen_pacibsp ());
+	    break;
+	  default:
+	    gcc_unreachable ();
+	}
       add_reg_note (insn, REG_CFA_TOGGLE_RA_MANGLE, const0_rtx);
       RTX_FRAME_RELATED_P (insn) = 1;
     }
@@ -5752,7 +5775,17 @@ aarch64_expand_epilogue (bool for_sibcall)
   if (aarch64_return_address_signing_enabled ()
       && (for_sibcall || !TARGET_ARMV8_3 || crtl->calls_eh_return))
     {
-      insn = emit_insn (gen_autisp ());
+      switch (aarch64_ra_sign_key)
+	{
+	  case AARCH64_KEY_A:
+	    insn = emit_insn (gen_autiasp ());
+	    break;
+	  case AARCH64_KEY_B:
+	    insn = emit_insn (gen_autibsp ());
+	    break;
+	  default:
+	    gcc_unreachable ();
+	}
       add_reg_note (insn, REG_CFA_TOGGLE_RA_MANGLE, const0_rtx);
       RTX_FRAME_RELATED_P (insn) = 1;
     }
@@ -15040,6 +15073,18 @@ aarch64_declare_function_name (FILE *stream, const char* name,
   ASM_OUTPUT_LABEL (stream, name);
 }
 
+/* Triggered after a .cfi_startproc directive is emitted into the assembly file.
+   Used to output the .cfi_b_key_frame directive when signing the current
+   function with the B key.  */
+
+void
+aarch64_post_cfi_startproc (FILE *f, tree ignored ATTRIBUTE_UNUSED)
+{
+  if (aarch64_return_address_signing_enabled ()
+      && aarch64_ra_sign_key == AARCH64_KEY_B)
+	asm_fprintf (f, "\t.cfi_b_key_frame\n");
+}
+
 /* Implements TARGET_ASM_FILE_START.  Output the assembly header.  */
 
 static void
@@ -18788,6 +18833,9 @@ aarch64_libgcc_floating_mode_supported_p
 #define TARGET_RUN_TARGET_SELFTESTS selftest::aarch64_run_selftests
 #endif /* #if CHECKING_P */
 
+#undef TARGET_ASM_POST_CFI_STARTPROC
+#define TARGET_ASM_POST_CFI_STARTPROC aarch64_post_cfi_startproc
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 
 #include "gt-aarch64.h"
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index cf2732e15e05db0a8825b1b7004fe904cc19ec19..f1d26e45fce13bc00cf018e44b8f3f6e9fdad3d1 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -118,8 +118,10 @@
 )
 
 (define_c_enum "unspec" [
-    UNSPEC_AUTI1716
-    UNSPEC_AUTISP
+    UNSPEC_AUTIA1716
+    UNSPEC_AUTIB1716
+    UNSPEC_AUTIASP
+    UNSPEC_AUTIBSP
     UNSPEC_CASESI
     UNSPEC_CRC32B
     UNSPEC_CRC32CB
@@ -162,8 +164,10 @@
     UNSPEC_LD4_LANE
     UNSPEC_MB
     UNSPEC_NOP
-    UNSPEC_PACI1716
-    UNSPEC_PACISP
+    UNSPEC_PACIA1716
+    UNSPEC_PACIB1716
+    UNSPEC_PACIASP
+    UNSPEC_PACIBSP
     UNSPEC_PRLG_STK
     UNSPEC_REV
     UNSPEC_RBIT
@@ -712,8 +716,12 @@
     if (aarch64_return_address_signing_enabled ()
 	&& TARGET_ARMV8_3
 	&& !crtl->calls_eh_return)
-      return "retaa";
-
+      {
+	if (aarch64_ra_sign_key == AARCH64_KEY_B)
+	  return "retab";
+	else
+	  return "retaa";
+      }
     return "ret";
   }
   [(set_attr "type" "branch")]
@@ -6543,7 +6551,7 @@
   [(set (reg:DI R30_REGNUM)
 	(unspec:DI [(reg:DI R30_REGNUM) (reg:DI SP_REGNUM)] PAUTH_LR_SP))]
   ""
-  "hint\t<pauth_hint_num_a> // <pauth_mnem_prefix>asp";
+  "hint\t<pauth_hint_num> // <pauth_mnem_prefix>sp";
 )
 
 ;; Signing/Authenticating X17 using X16 as the salt.
@@ -6552,7 +6560,7 @@
   [(set (reg:DI R17_REGNUM)
 	(unspec:DI [(reg:DI R17_REGNUM) (reg:DI R16_REGNUM)] PAUTH_17_16))]
   ""
-  "hint\t<pauth_hint_num_a> // <pauth_mnem_prefix>a1716";
+  "hint\t<pauth_hint_num> // <pauth_mnem_prefix>1716";
 )
 
 ;; Stripping the signature in R30.
diff --git a/gcc/config/aarch64/iterators.md b/gcc/config/aarch64/iterators.md
index ae75666167dd3c7787a2e2abb4136e85bef89420..1debf77e067e514d01b5ab3cba4199a0d8fa5635 100644
--- a/gcc/config/aarch64/iterators.md
+++ b/gcc/config/aarch64/iterators.md
@@ -1488,9 +1488,11 @@
 (define_int_iterator FMAXMIN_UNS [UNSPEC_FMAX UNSPEC_FMIN
 				  UNSPEC_FMAXNM UNSPEC_FMINNM])
 
-(define_int_iterator PAUTH_LR_SP [UNSPEC_PACISP UNSPEC_AUTISP])
+(define_int_iterator PAUTH_LR_SP [UNSPEC_PACIASP UNSPEC_AUTIASP
+				  UNSPEC_PACIBSP UNSPEC_AUTIBSP])
 
-(define_int_iterator PAUTH_17_16 [UNSPEC_PACI1716 UNSPEC_AUTI1716])
+(define_int_iterator PAUTH_17_16 [UNSPEC_PACIA1716 UNSPEC_AUTIA1716
+				  UNSPEC_PACIB1716 UNSPEC_AUTIB1716])
 
 (define_int_iterator VQDMULH [UNSPEC_SQDMULH UNSPEC_SQRDMULH])
 
@@ -1761,16 +1763,34 @@
 				  (UNSPEC_FCVTZU "fcvtzu")])
 
 ;; Pointer authentication mnemonic prefix.
-(define_int_attr pauth_mnem_prefix [(UNSPEC_PACISP "paci")
-				    (UNSPEC_AUTISP "auti")
-				    (UNSPEC_PACI1716 "paci")
-				    (UNSPEC_AUTI1716 "auti")])
-
-;; Pointer authentication HINT number for NOP space instructions using A Key.
-(define_int_attr pauth_hint_num_a [(UNSPEC_PACISP "25")
-				    (UNSPEC_AUTISP "29")
-				    (UNSPEC_PACI1716 "8")
-				    (UNSPEC_AUTI1716 "12")])
+(define_int_attr pauth_mnem_prefix [(UNSPEC_PACIASP "pacia")
+				    (UNSPEC_PACIBSP "pacib")
+				    (UNSPEC_PACIA1716 "pacia")
+				    (UNSPEC_PACIB1716 "pacib")
+				    (UNSPEC_AUTIASP "autia")
+				    (UNSPEC_AUTIBSP "autib")
+				    (UNSPEC_AUTIA1716 "autia")
+				    (UNSPEC_AUTIB1716 "autib")])
+
+(define_int_attr pauth_key [(UNSPEC_PACIASP "AARCH64_KEY_A")
+			    (UNSPEC_PACIBSP "AARCH64_KEY_B")
+			    (UNSPEC_PACIA1716 "AARCH64_KEY_A")
+			    (UNSPEC_PACIB1716 "AARCH64_KEY_B")
+			    (UNSPEC_AUTIASP "AARCH64_KEY_A")
+			    (UNSPEC_AUTIBSP "AARCH64_KEY_B")
+			    (UNSPEC_AUTIA1716 "AARCH64_KEY_A")
+			    (UNSPEC_AUTIB1716 "AARCH64_KEY_B")])
+
+;; Pointer authentication HINT number for NOP space instructions using A and
+;; B key.
+(define_int_attr pauth_hint_num [(UNSPEC_PACIASP "25")
+				   (UNSPEC_PACIBSP "27")
+				   (UNSPEC_AUTIASP "29")
+				   (UNSPEC_AUTIBSP "31")
+				   (UNSPEC_PACIA1716 "8")
+				   (UNSPEC_PACIB1716 "10")
+				   (UNSPEC_AUTIA1716 "12")
+				   (UNSPEC_AUTIB1716 "14")])
 
 (define_int_attr perm_insn [(UNSPEC_ZIP1 "zip") (UNSPEC_ZIP2 "zip")
 			    (UNSPEC_TRN1 "trn") (UNSPEC_TRN2 "trn")
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 99c67e3896dcf93c90384b08198523e94a754f7e..5171bf2d295f1800c5b41dd8b7d2f571fb542703 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -630,7 +630,8 @@ 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
+-mbranch-protection=@var{none}|@var{standard}|@var{pac-ret}[+@var{leaf}
++@var{b-key}] @gol
 -march=@var{name}  -mcpu=@var{name}  -mtune=@var{name}  @gol
 -moverride=@var{string}  -mverbose-cost-dump  -mtrack-speculation} 
 
@@ -15704,7 +15705,8 @@ functions, and @samp{all}, which enables pointer signing for all functions.  The
 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}]
+@item -mbranch-protection=@var{none}|@var{standard}|@var{pac-ret}[+@var{leaf}
++@var{b-key}]
 @opindex mbranch-protection
 Select the branch protection features to use.
 @samp{none} is the default and turns off all types of branch protection.
@@ -15715,7 +15717,8 @@ level.
 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.
+functions.  The optional argument @samp{b-key} can be used to sign the functions
+with the B-key instead of the A-key.
 
 @item -msve-vector-bits=@var{bits}
 @opindex msve-vector-bits
diff --git a/gcc/testsuite/gcc.target/aarch64/return_address_sign_ab_exception.cpp b/gcc/testsuite/gcc.target/aarch64/return_address_sign_ab_exception.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e644333f4f569e96cc38a5e523c1008e63c5d642
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/return_address_sign_ab_exception.cpp
@@ -0,0 +1,29 @@
+/* { dg-do run } */
+/* { dg-options "--save-temps" } */
+
+__attribute__((target("branch-protection=pac-ret+leaf")))
+int foo_a () {
+  throw 22;
+}
+
+__attribute__((target("branch-protection=pac-ret+leaf+b-key")))
+int foo_b () {
+  throw 22;
+}
+
+int main (int argc, char** argv) {
+  try {
+    foo_a ()
+  } catch (...) {
+    try {
+      foo_b ();
+    } catch (...) {
+      return 0;
+    }
+  }
+  return 1;
+}
+
+/* { dg-final { scan-assembler-times "paciasp" 1 } } */
+/* { dg-final { scan-assembler-times "pacibsp" 1 } } */
+/* { dg-final { scan-assembler-times "\t\t.cfi_b_key_frame" 1 } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/return_address_sign_b_1.c b/gcc/testsuite/gcc.target/aarch64/return_address_sign_b_1.c
new file mode 100644
index 0000000000000000000000000000000000000000..32d788ddf3fb72545d7c4b9869d8e445bdaaab37
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/return_address_sign_b_1.c
@@ -0,0 +1,52 @@
+/* Testing return address signing where no combined instructions used.  */
+/* { dg-do compile } */
+/* { dg-options "-O2 -mbranch-protection=pac-ret+leaf+b-key" } */
+/* { dg-require-effective-target lp64 } */
+
+int foo (int);
+
+/* sibcall only.  */
+int __attribute__ ((target ("arch=armv8.3-a")))
+func1 (int a, int b)
+{
+  /* pacibsp */
+  return foo (a + b);
+  /* autibsp */
+}
+
+/* non-leaf function with sibcall.  */
+int __attribute__ ((target ("arch=armv8.3-a")))
+func2 (int a, int b)
+{
+  /* pacibsp */
+  if (a < b)
+    return b;
+
+  a = foo (b);
+
+  return foo (a);
+  /* autibsp */
+}
+
+/* non-leaf function, legacy arch.  */
+int __attribute__ ((target ("arch=armv8.2-a")))
+func3 (int a, int b, int c)
+{
+  /* pacibsp */
+  return a + foo (b) + c;
+  /* autibsp */
+}
+
+/* eh_return.  */
+void __attribute__ ((target ("arch=armv8.3-a")))
+func4 (long offset, void *handler, int *ptr, int imm1, int imm2)
+{
+  /* pacibsp */
+  *ptr = imm1 + foo (imm1) + imm2;
+  __builtin_eh_return (offset, handler);
+  /* autibsp */
+  return;
+}
+
+/* { dg-final { scan-assembler-times "pacibsp" 4 } } */
+/* { dg-final { scan-assembler-times "autibsp" 4 } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/return_address_sign_b_2.c b/gcc/testsuite/gcc.target/aarch64/return_address_sign_b_2.c
new file mode 100644
index 0000000000000000000000000000000000000000..9ed64ce05911475268e9ef95e88e873e21611085
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/return_address_sign_b_2.c
@@ -0,0 +1,18 @@
+/* Testing return address signing where combined instructions used.  */
+/* { dg-do compile } */
+/* { dg-options "-O2 -mbranch-protection=pac-ret+leaf+b-key" } */
+/* { dg-require-effective-target lp64 } */
+
+int foo (int);
+int bar (int, int);
+
+int __attribute__ ((target ("arch=armv8.3-a")))
+func1 (int a, int b, int c)
+{
+  /* pacibsp */
+  return a + foo (b) + c;
+  /* retab */
+}
+
+/* { dg-final { scan-assembler-times "pacibsp" 1 } } */
+/* { dg-final { scan-assembler-times "retab" 1 } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/return_address_sign_b_3.c b/gcc/testsuite/gcc.target/aarch64/return_address_sign_b_3.c
new file mode 100644
index 0000000000000000000000000000000000000000..111a30e0bfd246ffa3c2765955cd6d3463a7a715
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/return_address_sign_b_3.c
@@ -0,0 +1,22 @@
+/* Testing the disable of return address signing.  */
+/* { dg-do compile } */
+/* { dg-options "-O2 -mbranch-protection=pac-ret+leaf+b-key" } */
+/* { dg-require-effective-target lp64 } */
+
+int bar (int, int);
+
+int __attribute__ ((target ("arch=armv8.3-a, branch-protection=pac-ret+b-key")))
+func1_leaf (int a, int b, int c, int d)
+{
+  return a + b + c + d;
+}
+
+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;
+}
+
+/* { dg-final { scan-assembler-not "pacibsp" } } */
+/* { dg-final { scan-assembler-not "autibsp" } } */
+/* { dg-final { scan-assembler-not "retab" } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/return_address_sign_b_exception.cpp b/gcc/testsuite/gcc.target/aarch64/return_address_sign_b_exception.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..44dcfee245e05c832f72cc58cf00ee6e726ed5b0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/return_address_sign_b_exception.cpp
@@ -0,0 +1,17 @@
+/* { dg-do run } */
+/* { dg-options "-mbranch-protection=pac-ret+leaf+b-key"} */
+
+int foo () {
+  throw 22;
+}
+
+int main (int argc, char** argv) {
+  try {
+    foo()
+  } catch (...) {
+    return 0;
+  }
+  return 1;
+}
+
+/* { dg-final { scan-assembler-times ".cfi_b_key_frame" 2 } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/return_address_sign_builtin.c b/gcc/testsuite/gcc.target/aarch64/return_address_sign_builtin.c
new file mode 100644
index 0000000000000000000000000000000000000000..0a01bfc9da45589740f9939d780805c27379c650
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/return_address_sign_builtin.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-mbranch-protection=pac-ret+leaf+b-key" } */
+
+/* The correct pauth instruction should be generated no matter the return
+  address signing key/scope specified in the options.  */
+
+int foo() {
+  /* { dg-final { scan-assembler-times "pacia1716" 1 } } */
+  __builtin_aarch64_pacia1716(0, 0);
+  /* { dg-final { scan-assembler-times "pacib1716" 1 } } */
+  __builtin_aarch64_pacib1716(0, 0);
+  /* { dg-final { scan-assembler-times "autia1716" 1 } } */
+  __builtin_aarch64_autia1716(0, 0);
+  /* { dg-final { scan-assembler-times "autib1716" 1 } } */
+  __builtin_aarch64_autib1716(0, 0);
+}
diff --git a/libgcc/config/aarch64/aarch64-unwind.h b/libgcc/config/aarch64/aarch64-unwind.h
index ff05226f49cba67cf909c1edac8bd8c25f6f71d8..5e7bf64e4a7983ff38c7456bc918a016a21e5bcd 100644
--- a/libgcc/config/aarch64/aarch64-unwind.h
+++ b/libgcc/config/aarch64/aarch64-unwind.h
@@ -35,6 +35,23 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 #define MD_FROB_UPDATE_CONTEXT(context, fs) \
   aarch64_frob_update_context (context, fs)
 
+static inline int
+aarch64_cie_signed_with_b_key (struct _Unwind_Context *context)
+{
+  const struct dwarf_fde *fde = _Unwind_Find_FDE (context->bases.func,
+						  &context->bases);
+  if (fde != NULL)
+    {
+      const struct dwarf_cie *cie = get_cie (fde);
+      if (cie != NULL)
+	{
+	  char *aug_str = cie->augmentation;
+	  return strchr (aug_str, 'B') == NULL ? 0 : 1;
+	}
+    }
+  return 0;
+}
+
 /* Do AArch64 private extraction on ADDR based on context info CONTEXT and
    unwind frame info FS.  If ADDR is signed, we do address authentication on it
    using CFA of current frame.  */
@@ -43,9 +60,11 @@ static inline void *
 aarch64_post_extract_frame_addr (struct _Unwind_Context *context,
 				 _Unwind_FrameState *fs, void *addr)
 {
-  if (fs->regs.reg[DWARF_REGNUM_AARCH64_RA_STATE].loc.offset & 0x1)
+  if (context->flags & RA_SIGNED_BIT)
     {
       _Unwind_Word salt = (_Unwind_Word) context->cfa;
+      if (aarch64_cie_signed_with_b_key (context) != 0)
+	return __builtin_aarch64_autib1716 (addr, salt);
       return __builtin_aarch64_autia1716 (addr, salt);
     }
   else
@@ -62,9 +81,14 @@ aarch64_post_frob_eh_handler_addr (struct _Unwind_Context *current,
 				   ATTRIBUTE_UNUSED,
 				   void *handler_addr)
 {
-  if (current->flags & RA_A_SIGNED_BIT)
-    return __builtin_aarch64_pacia1716 (handler_addr,
+  if (current->flags & RA_SIGNED_BIT)
+    {
+      if (aarch64_cie_signed_with_b_key (current))
+	return __builtin_aarch64_pacib1716 (handler_addr,
+					    (_Unwind_Word) current->cfa);
+      return __builtin_aarch64_pacia1716 (handler_addr,
 					(_Unwind_Word) current->cfa);
+    }
   else
     return handler_addr;
 }
@@ -79,7 +103,7 @@ aarch64_frob_update_context (struct _Unwind_Context *context,
 {
   if (fs->regs.reg[DWARF_REGNUM_AARCH64_RA_STATE].loc.offset & 0x1)
     /* The flag is used for re-authenticating EH handler's address.  */
-    context->flags |= RA_A_SIGNED_BIT;
+    context->flags |= RA_SIGNED_BIT;
 
   return;
 }
diff --git a/libgcc/unwind-dw2-fde.c b/libgcc/unwind-dw2-fde.c
index 0d52b7a4cefb35efc744b9a2c374460ce37ab470..9b454270ffd4cf188ab18c6b2261343166e64331 100644
--- a/libgcc/unwind-dw2-fde.c
+++ b/libgcc/unwind-dw2-fde.c
@@ -334,6 +334,9 @@ get_cie_encoding (const struct dwarf_cie *cie)
       /* LSDA encoding.  */
       else if (*aug == 'L')
 	p++;
+      /* aarch64 b-key pointer authentication.  */
+      else if (*aug == 'B')
+	p++;
       /* Otherwise end of string, or unknown augmentation.  */
       else
 	return DW_EH_PE_absptr;
diff --git a/libgcc/unwind-dw2.c b/libgcc/unwind-dw2.c
index de9310f524fc1f5103b6df2e024c50454a53a1c0..f2b1cfd246197977837ee4ee5311781df1bf5a05 100644
--- a/libgcc/unwind-dw2.c
+++ b/libgcc/unwind-dw2.c
@@ -136,8 +136,9 @@ struct _Unwind_Context
 #define SIGNAL_FRAME_BIT ((~(_Unwind_Word) 0 >> 1) + 1)
   /* Context which has version/args_size/by_value fields.  */
 #define EXTENDED_CONTEXT_BIT ((~(_Unwind_Word) 0 >> 2) + 1)
-  /* Bit reserved on AArch64, return address has been signed with A key.  */
-#define RA_A_SIGNED_BIT ((~(_Unwind_Word) 0 >> 3) + 1)
+  /* Bit reserved on AArch64, return address has been signed with A or B
+     key.  */
+#define RA_SIGNED_BIT ((~(_Unwind_Word) 0 >> 3) + 1)
   _Unwind_Word flags;
   /* 0 for now, can be increased when further fields are added to
      struct _Unwind_Context.  */
@@ -502,6 +503,11 @@ extract_cie_info (const struct dwarf_cie *cie, struct _Unwind_Context *context,
 	  fs->signal_frame = 1;
 	  aug += 1;
 	}
+      /* aarch64 B-key pointer authentication.  */
+      else if (aug[0] == 'B')
+	{
+	  aug += 1;
+      }
 
       /* Otherwise we have an unknown augmentation string.
 	 Bail unless we saw a 'z' prefix.  */

  reply	other threads:[~2018-12-21 15:00 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-11-02 17:35 Sam Tebbs
2018-11-02 18:02 ` Sam Tebbs
2018-11-09 11:05   ` Sam Tebbs
2018-12-21 15:04     ` Sam Tebbs [this message]
2019-01-04 16:56       ` Sam Tebbs
2019-01-07 18:28       ` James Greenhalgh
2019-01-08 11:38         ` Sam Tebbs
2019-01-14 10:44           ` Kyrill Tkachov
2019-01-23 10:43             ` Sam Tebbs
2019-01-31 14:56               ` Sam Tebbs
2019-03-01 14:12                 ` Sam Tebbs
2019-05-29  9:29                   ` Sam Tebbs
2019-05-29 11:53                     ` Christophe Lyon
2019-05-29 14:24                       ` Sam Tebbs
2019-05-30 12:29                         ` Sam Tebbs

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=f284bc8a-8bca-feb5-2d90-deced94cef20@arm.com \
    --to=sam.tebbs@arm.com \
    --cc=James.Greenhalgh@arm.com \
    --cc=Marcus.Shawcroft@arm.com \
    --cc=Richard.Earnshaw@arm.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=nd@arm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).