[PATCH 3/3][GCC][AARCH64] Add support for pointer authentication B key
authorSam Tebbs <sam.tebbs@arm.com>
Wed, 29 May 2019 09:22:17 +0000 (09:22 +0000)
committerSam Tebbs <samtebbs@gcc.gnu.org>
Wed, 29 May 2019 09:22:17 +0000 (09:22 +0000)
gcc/
2019-05-29  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_handle_standard_branch_protection,
aarch64_handle_pac_ret_protection): Set default sign key to A.
* config/aarch64/aarch64.c (aarch64_expand_epilogue,
aarch64_expand_prologue): 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.
* doc/invoke.texi (-mbranch-protection): Add b-key type.
* config/aarch64/aarch64-bti-insert.c (aarch64_pac_insn_p): Rename
UNSPEC_PACISP to UNSPEC_PACIASP and UNSPEC_PACIBSP.

gcc/testsuite
2019-05-29  Sam Tebbs  <sam.tebbs@arm.com>

* 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_ab_exception.c: New file.
* gcc.target/aarch64/return_address_sign_builtin.c: New file

libgcc/
2019-05-29  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.
* config/aarch64/aarch64-unwind-h (aarch64_post_extract_frame_addr,
aarch64_post_frob_eh_handler_addr, aarch64_post_frob_update_context):
Rename RA_A_SIGNED_BIT to RA_SIGNED_BIT.
* 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.
(RA_A_SIGNED_BIT): Rename to RA_SIGNED_BIT.

From-SVN: r271735

14 files changed:
gcc/ChangeLog
gcc/config/aarch64/aarch64-bti-insert.c
gcc/config/aarch64/aarch64-builtins.c
gcc/config/aarch64/aarch64-protos.h
gcc/config/aarch64/aarch64.c
gcc/config/aarch64/aarch64.h
gcc/config/aarch64/aarch64.md
gcc/config/aarch64/iterators.md
gcc/doc/invoke.texi
gcc/testsuite/ChangeLog
libgcc/ChangeLog
libgcc/config/aarch64/aarch64-unwind.h
libgcc/unwind-dw2-fde.c
libgcc/unwind-dw2.c

index f008e7805de0a6120aefd19747c8ec232cd207c3..407b248b5ac831287be5a7e2ec143bb0e45f3312 100644 (file)
@@ -1,3 +1,47 @@
+2019-05-29  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_handle_standard_branch_protection,
+       aarch64_handle_pac_ret_protection): Set default sign key to A.
+       * config/aarch64/aarch64.c (aarch64_expand_epilogue,
+       aarch64_expand_prologue): 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.
+       * doc/invoke.texi (-mbranch-protection): Add b-key type.
+       * config/aarch64/aarch64-bti-insert.c (aarch64_pac_insn_p): Rename
+       UNSPEC_PACISP to UNSPEC_PACIASP and UNSPEC_PACIBSP.
+
 2019-05-29  Jakub Jelinek  <jakub@redhat.com>
 
        * gimplify.c (struct gimplify_omp_ctx): Add clauses member.
index e519a0f0ac1751f4268e03381757bc1a10c13144..db8ebb1ba8e45b4bf7cd2f27ae8a2c606a1a6c89 100644 (file)
@@ -106,7 +106,9 @@ aarch64_pac_insn_p (rtx x)
          int unspec_val = XINT (sub, 1);
          switch (unspec_val)
            {
-           case UNSPEC_PACISP:
+           case UNSPEC_PACIASP:
+            /* fall-through.  */
+            case UNSPEC_PACIBSP:
              return true;
 
            default:
index d7b1b7bd6867a0f98a2f67fec0fd80a0a08f69c1..549a6c249243372eacb5d29923b5d1abce4ac79a 100644 (file)
@@ -432,6 +432,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,
   /* Special cased Armv8.3-A Complex FMA by Lane quad Builtins.  */
   AARCH64_SIMD_FCMLA_LANEQ_BUILTIN_BASE,
@@ -1051,6 +1053,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,
@@ -1540,6 +1550,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));
@@ -1563,8 +1575,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);
index a0723266f22454ce3d4d57830573acdebc96489c..4485e0f354b351901f7de71585922a0407c4dd53 100644 (file)
@@ -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);
index 83453d03095018eddd1801e71ef3836849267444..9e4b335244acea03d974521a2dc6a914317e7727 100644 (file)
@@ -1172,6 +1172,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;
 
@@ -1241,6 +1243,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;
   aarch64_enable_bti = 1;
   if (rest)
     {
@@ -1255,6 +1258,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;
 }
 
@@ -1266,6 +1270,14 @@ aarch64_handle_pac_ret_leaf (char* str ATTRIBUTE_UNUSED,
   return AARCH64_PARSE_OK;
 }
 
+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 enum aarch64_parse_opt_result
 aarch64_handle_bti_protection (char* str ATTRIBUTE_UNUSED,
                                    char* rest ATTRIBUTE_UNUSED)
@@ -1276,6 +1288,7 @@ aarch64_handle_bti_protection (char* str ATTRIBUTE_UNUSED,
 
 static const struct aarch64_branch_protect_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 }
 };
 
@@ -4852,7 +4865,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));
@@ -5651,7 +5664,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;
     }
@@ -5907,7 +5930,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;
     }
@@ -15330,6 +15363,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
@@ -19341,6 +19386,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"
index be6981889ab6a796183ef1fd96c3af99243f4466..4b3e2f97d61591e162bd60189103ec9b569988b2 100644 (file)
@@ -512,6 +512,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 ()
index 5a1894063a1ed2db1cc947c9c449d48808ed96ae..49582f2e7e4fb51f6c7fa60639c56fd862147b27 100644 (file)
 )
 
 (define_c_enum "unspec" [
-    UNSPEC_AUTI1716
-    UNSPEC_AUTISP
+    UNSPEC_AUTIA1716
+    UNSPEC_AUTIB1716
+    UNSPEC_AUTIASP
+    UNSPEC_AUTIBSP
     UNSPEC_CASESI
     UNSPEC_CRC32B
     UNSPEC_CRC32CB
     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
     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")]
   [(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.
   [(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.
index 20aa0e9d2b80192ff7ffbac00d1bae79026a8753..d0070b1a73218822976acb846638ee385d8a4f2c 100644 (file)
 (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])
 
                                  (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")
index b722559d31a1009a10d379c19c280af0bd1f63bd..3e4f012b4fa47f5bbcac6e44542e51b601d8a968 100644 (file)
@@ -632,7 +632,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}]|@var{bti} @gol
+-mbranch-protection=@var{none}|@var{standard}|@var{pac-ret}[+@var{leaf}
++@var{b-key}]|@var{bti} @gol
 -march=@var{name}  -mcpu=@var{name}  -mtune=@var{name}  @gol
 -moverride=@var{string}  -mverbose-cost-dump @gol
 -mstack-protector-guard=@var{guard} -mstack-protector-guard-reg=@var{sysreg} @gol
@@ -15900,7 +15901,7 @@ 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}]|@var{bti}
+@item -mbranch-protection=@var{none}|@var{standard}|@var{pac-ret}[+@var{leaf}+@var{b-key}]|@var{bti}
 @opindex mbranch-protection
 Select the branch protection features to use.
 @samp{none} is the default and turns off all types of branch protection.
@@ -15911,7 +15912,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.
 @samp{bti} turns on branch target identification mechanism.
 
 @item -msve-vector-bits=@var{bits}
index aec79b1e6b9191d1a32fee8de1304c4052878410..71982226f080f41aa8ae642de3534a9c37329230 100644 (file)
@@ -1,3 +1,12 @@
+2019-05-29  Sam Tebbs  <sam.tebbs@arm.com>
+
+       * 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_ab_exception.c: New file.
+       * gcc.target/aarch64/return_address_sign_builtin.c: New file
+
 2019-05-29  Jakub Jelinek  <jakub@redhat.com>
 
        * c-c++-common/gomp/lastprivate-conditional-2.c (foo): Don't expect
index 316c203565edf4b7e213b8d4f0b73f9f9e30f8ad..c86decfab0ed1d28421c6deccb578478e79deb5f 100644 (file)
@@ -1,3 +1,18 @@
+2019-05-29  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.
+       * config/aarch64/aarch64-unwind-h (aarch64_post_extract_frame_addr,
+       aarch64_post_frob_eh_handler_addr, aarch64_post_frob_update_context):
+       Rename RA_A_SIGNED_BIT to RA_SIGNED_BIT.
+       * 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.
+       (RA_A_SIGNED_BIT): Rename to RA_SIGNED_BIT.
+
 2019-05-28  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>
 
        * config/sparc/sol2-unwind.h [__arch64__] (sparc64_is_sighandler):
index 223ac9157f1e33f711c93c54d8d9b7a4cce00206..13e6e4a6a01ad5228f15fbb40672d72d8fb4d30d 100644 (file)
@@ -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;
 }
index 24b4ecee68c17e1701c4482580e449b03a4e6fe9..40ebf85a93ec840917fc4feb48a9e0f843e42324 100644 (file)
@@ -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;
index e6130af2fb54d1abca80baba1af5cd1e48ee7410..e76a1cbc4620a5d2eb734e5071e60e58acf74743 100644 (file)
@@ -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.  */