From 8fc16d725206f2c40bae423d7d0d93bd1baf6da2 Mon Sep 17 00:00:00 2001 From: Sam Tebbs Date: Wed, 29 May 2019 09:22:17 +0000 Subject: [PATCH 3/3][GCC][AARCH64] Add support for pointer authentication B key gcc/ 2019-05-29 Sam Tebbs * 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 (sp): Replace pauth_hint_num_a with pauth_hint_num. * config/aarch64/aarch64.md (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 * 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 * 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 --- libgcc/ChangeLog | 15 +++++++++++++++ libgcc/config/aarch64/aarch64-unwind.h | 32 ++++++++++++++++++++++++++++---- libgcc/unwind-dw2-fde.c | 3 +++ libgcc/unwind-dw2.c | 10 ++++++++-- 4 files changed, 54 insertions(+), 6 deletions(-) (limited to 'libgcc') diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog index 316c203..c86decf 100644 --- a/libgcc/ChangeLog +++ b/libgcc/ChangeLog @@ -1,3 +1,18 @@ +2019-05-29 Sam Tebbs + + * 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 * config/sparc/sol2-unwind.h [__arch64__] (sparc64_is_sighandler): diff --git a/libgcc/config/aarch64/aarch64-unwind.h b/libgcc/config/aarch64/aarch64-unwind.h index 223ac91..13e6e4a 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 24b4ece..40ebf85 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 e6130af..e76a1cb 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. */ -- cgit v1.1