From 09038062534606ef9100b5474d136f7d2e543de4 Mon Sep 17 00:00:00 2001 From: Sam Tebbs Date: Thu, 13 Dec 2018 16:27:01 +0000 Subject: [PATCH] Move aarch64 CIE code to aarch64 backend 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 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 | 4 ++++ binutils/dwarf.c | 2 ++ gas/ChangeLog | 14 ++++++++++++++ gas/config/tc-aarch64.h | 37 +++++++++++++++++++++++++++++++++++++ gas/dw2gencfi.c | 22 ++++++++++++++++------ gas/dw2gencfi.h | 10 +++------- 6 files changed, 76 insertions(+), 13 deletions(-) diff --git a/binutils/ChangeLog b/binutils/ChangeLog index a1fce1adc5..12d480215c 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,7 @@ +2018-12-13 Sam Tebbs + + * dwarf.c (read_cie): Add check for 'B'. + 2018-12-11 Nick Clifton * NEWS: Note that recursion limit has increased to 2048. diff --git a/binutils/dwarf.c b/binutils/dwarf.c index a85a9ab2e3..e786bc4856 100644 --- a/binutils/dwarf.c +++ b/binutils/dwarf.c @@ -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++; diff --git a/gas/ChangeLog b/gas/ChangeLog index 98b35adb11..dc3aa7ceb8 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,17 @@ +2018-12-13 Sam Tebbs + + * 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 * testsuite/gas/arm/blx-local-thumb.d: Skip arm-nto and diff --git a/gas/config/tc-aarch64.h b/gas/config/tc-aarch64.h index 88df2aaaf0..93e8f80d92 100644 --- a/gas/config/tc-aarch64.h +++ b/gas/config/tc-aarch64.h @@ -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; } diff --git a/gas/dw2gencfi.c b/gas/dw2gencfi.c index ff5c0df7f6..02d7f3c48a 100644 --- a/gas/dw2gencfi.c +++ b/gas/dw2gencfi.c @@ -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 diff --git a/gas/dw2gencfi.h b/gas/dw2gencfi.h index 2b1362a2bb..308032f831 100644 --- a/gas/dw2gencfi.h +++ b/gas/dw2gencfi.h @@ -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. */ -- 2.34.1