Move aarch64 CIE code to aarch64 backend
authorSam Tebbs <sam.tebbs@arm.com>
Thu, 13 Dec 2018 16:27:01 +0000 (16:27 +0000)
committerThomas Preud'homme <thomas.preudhomme@linaro.org>
Thu, 13 Dec 2018 16:37:40 +0000 (16:37 +0000)
This commit moves all aarch64-specific code to deal with CIE structure
introduced in 3a67e1a6b4430374f3073e51bb19347d4c421cfe from
target-independent files to the aarch64 backend.

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

binutils/
* dwarf.c (read_cie):  Add check for 'B'.

gas/
* config/tc-aarch64.h (enum pointer_auth_key,
tc_fde_entry_extras, tc_cie_entry_extras, tc_fde_entry_init_extra,
tc_output_cie_extra, tc_cie_fde_equivalent_extra,
tc_cie_entry_init_extra): Define.
* dw2gencfi.c (struct cie_entry): Add tc_cie_entry_extras invocation.
(alloc_fde_entry, select_cie_for_fde): Add tc_fde_entry_init_extra
invocation.
(output_cie): Add tc_output_cie_extra invocation.
(select_cie_for_fde): Add tc_cie_fde_equivalent_extra invocation.
* dw2gencfi.h (enum pointer_auth_key): Move to config/tc-aarch64.h.
(struct fde_entry): Add tc_fde_entry_extras invocation

binutils/ChangeLog
binutils/dwarf.c
gas/ChangeLog
gas/config/tc-aarch64.h
gas/dw2gencfi.c
gas/dw2gencfi.h

index a1fce1adc5888be409f4acb9746326e33570b25a..12d480215ce80f83e0aeeb92eeb767456bbb688b 100644 (file)
@@ -1,3 +1,7 @@
+2018-12-13  Sam Tebbs  <sam.tebbs@arm.com>
+
+       * dwarf.c (read_cie):  Add check for 'B'.
+
 2018-12-11  Nick Clifton  <nickc@redhat.com>
 
        * NEWS: Note that recursion limit has increased to 2048.
index a85a9ab2e3c5b3092d70838156b40dbff608b652..e786bc48564a7c3233d72b1260fdf8b020935f3d 100644 (file)
@@ -7401,6 +7401,8 @@ read_cie (unsigned char *start, unsigned char *end,
            fc->fde_encoding = *q++;
          else if (*p == 'S')
            ;
+         else if (*p == 'B')
+           ;
          else
            break;
          p++;
index 98b35adb11d3410320aab4a406f1883e7de2f085..dc3aa7ceb8a1054a420e06d0b1e15cd24d8219bd 100644 (file)
@@ -1,3 +1,17 @@
+2018-12-13  Sam Tebbs  <sam.tebbs@arm.com>
+
+       * config/tc-aarch64.h (enum pointer_auth_key,
+       tc_fde_entry_extras, tc_cie_entry_extras, tc_fde_entry_init_extra,
+       tc_output_cie_extra, tc_cie_fde_equivalent_extra,
+       tc_cie_entry_init_extra): Define.
+       * dw2gencfi.c (struct cie_entry): Add tc_cie_entry_extras invocation.
+       (alloc_fde_entry, select_cie_for_fde): Add tc_fde_entry_init_extra
+       invocation.
+       (output_cie): Add tc_output_cie_extra invocation.
+       (select_cie_for_fde): Add tc_cie_fde_equivalent_extra invocation.
+       * dw2gencfi.h (enum pointer_auth_key): Move to config/tc-aarch64.h.
+       (struct fde_entry): Add tc_fde_entry_extras invocation
+
 2018-12-12  Andre Vieira  <andre.simoesdiasvieira@arm.com>
 
        * testsuite/gas/arm/blx-local-thumb.d: Skip arm-nto and
index 88df2aaaf0d762a0a76a85981a402e454ec17069..93e8f80d9290ee78051cb362c9ac65847d6633cf 100644 (file)
@@ -80,6 +80,43 @@ struct aarch64_fix
 
 #define tc_frob_section(S) aarch64_frob_section (S)
 
+/* The key used to sign a function's return address.  */
+enum pointer_auth_key {
+  AARCH64_PAUTH_KEY_A,
+  AARCH64_PAUTH_KEY_B
+};
+
+/* The extra fields required by AArch64 in fde_entry and cie_entry.  Currently
+   only used to store the key used to sign the frame's return address.  */
+#define tc_fde_entry_extras enum pointer_auth_key pauth_key;
+#define tc_cie_entry_extras enum pointer_auth_key pauth_key;
+
+/* The extra initialisation steps needed by AArch64 in alloc_fde_entry.
+   Currently only used to initialise the key used to sign the return
+   address.  */
+#define tc_fde_entry_init_extra(fde) fde->pauth_key = AARCH64_PAUTH_KEY_A;
+
+/* Extra checks required by AArch64 when outputting the current cie_entry.
+   Currently only used to output a 'B' if the return address is signed with the
+   B key.  */
+#define tc_output_cie_extra(cie) \
+    do \
+      { \
+       if (cie->pauth_key == AARCH64_PAUTH_KEY_B) \
+         out_one ('B'); \
+      } \
+    while (0)
+
+/* Extra equivalence checks required by AArch64 when selecting the correct cie
+   for some fde.  Currently only used to check for quivalence between keys used
+   to sign ther return address.  */
+#define tc_cie_fde_equivalent_extra(cie, fde) (cie->pauth_key == fde->pauth_key)
+
+/* The extra initialisation steps needed by AArch64 in select_cie_for_fde.
+   Currently only used to initialise the key used to sign the return
+   address.  */
+#define tc_cie_entry_init_extra(cie, fde) cie->pauth_key = fde->pauth_key;
+
 #define TC_FIX_TYPE struct aarch64_fix
 #define TC_INIT_FIX_DATA(FIX) { (FIX)->tc_fix_data.inst = NULL;        \
     (FIX)->tc_fix_data.opnd = AARCH64_OPND_NIL; }
index ff5c0df7f61210c544faaeb46520c4f235826569..02d7f3c48a36cd20220b644359227ca16650203a 100644 (file)
@@ -403,7 +403,9 @@ struct cie_entry
   unsigned char per_encoding;
   unsigned char lsda_encoding;
   expressionS personality;
-  enum pointer_auth_key pauth_key;
+#ifdef tc_cie_entry_extras
+  tc_cie_entry_extras
+#endif
   struct cfi_insn_data *first, *last;
 };
 
@@ -433,7 +435,9 @@ alloc_fde_entry (void)
   fde->per_encoding = DW_EH_PE_omit;
   fde->lsda_encoding = DW_EH_PE_omit;
   fde->eh_header_type = EH_COMPACT_UNKNOWN;
-  fde->pauth_key = AARCH64_PAUTH_KEY_A;
+#ifdef tc_fde_entry_init_extra
+  tc_fde_entry_init_extra (fde)
+#endif
 
   return fde;
 }
@@ -1858,8 +1862,9 @@ output_cie (struct cie_entry *cie, bfd_boolean eh_frame, int align)
       if (cie->lsda_encoding != DW_EH_PE_omit)
        out_one ('L');
       out_one ('R');
-      if (cie->pauth_key == AARCH64_PAUTH_KEY_B)
-       out_one ('B');
+#ifdef tc_output_cie_extra
+      tc_output_cie_extra (cie)
+#endif
     }
   if (cie->signal_frame)
     out_one ('S');
@@ -2039,8 +2044,11 @@ select_cie_for_fde (struct fde_entry *fde, bfd_boolean eh_frame,
     {
       if (CUR_SEG (cie) != CUR_SEG (fde))
        continue;
+#ifdef tc_cie_fde_equivalent_extra
+      if (!tc_cie_fde_equivalent_extra (cie, fde))
+       continue;
+#endif
       if (cie->return_column != fde->return_column
-         || cie->pauth_key != fde->pauth_key
          || cie->signal_frame != fde->signal_frame
          || cie->per_encoding != fde->per_encoding
          || cie->lsda_encoding != fde->lsda_encoding)
@@ -2147,7 +2155,9 @@ select_cie_for_fde (struct fde_entry *fde, bfd_boolean eh_frame,
   cie->lsda_encoding = fde->lsda_encoding;
   cie->personality = fde->personality;
   cie->first = fde->data;
-  cie->pauth_key = fde->pauth_key;
+#ifdef tc_cie_entry_init_extra
+  tc_cie_entry_init_extra (cie, fde)
+#endif
 
   for (i = cie->first; i ; i = i->next)
     if (i->insn == DW_CFA_advance_loc
index 2b1362a2bb02161e8b9e6c8b781e38f39fd319d8..308032f8319aa823cb0a2b61f190e9e850d88a36 100644 (file)
@@ -135,11 +135,6 @@ enum {
   EH_COMPACT_HAS_LSDA
 };
 
-enum pointer_auth_key {
-  AARCH64_PAUTH_KEY_A,
-  AARCH64_PAUTH_KEY_B
-};
-
 /* Stack of old CFI data, for save/restore.  */
 struct cfa_save_data
 {
@@ -183,8 +178,9 @@ struct fde_entry
   /* For out of line tables and FDEs.  */
   symbolS *eh_loc;
   int sections;
-  /* The pointer authentication key used.  Only used for AArch64.  */
-  enum pointer_auth_key pauth_key;
+#ifdef tc_fde_entry_extras
+  tc_fde_entry_extras
+#endif
 };
 
 /* The list of all FDEs that have been collected.  */