From 3369de90b81592b44ba34360642a74a68afbdf7a Mon Sep 17 00:00:00 2001 From: Indu Bhagat Date: Thu, 22 Dec 2022 09:57:16 -0800 Subject: gas: sframe: add support for .cfi_b_key_frame Gather the information from the DWARF FDE on whether frame's return addresses are signed using the B key or A key. Reflect the information in the SFrame counterpart data structure, the SFrame FDE. ChangeLog: * gas/gen-sframe.c (get_dw_fde_pauth_b_key_p): New definition. (sframe_v1_set_func_info): Add new argument for pauth_key. (sframe_set_func_info): Likewise. (output_sframe_funcdesc): Likewise. * gas/gen-sframe.h (struct sframe_version_ops): Add new argument to the function pointer declaration. * gas/sframe-opt.c (sframe_convert_frag): Handle pauth_key. --- gas/gen-sframe.c | 26 ++++++++++++++++++++++---- gas/gen-sframe.h | 2 +- gas/sframe-opt.c | 3 +++ 3 files changed, 26 insertions(+), 5 deletions(-) (limited to 'gas') diff --git a/gas/gen-sframe.c b/gas/gen-sframe.c index 9baf20b..76f8529 100644 --- a/gas/gen-sframe.c +++ b/gas/gen-sframe.c @@ -106,6 +106,17 @@ get_dw_fde_end_addrS (const struct fde_entry *dw_fde) return dw_fde->end_address; } +/* Get whether PAUTH B key is used. */ +static bool +get_dw_fde_pauth_b_key_p (const struct fde_entry *dw_fde ATTRIBUTE_UNUSED) +{ +#ifdef tc_fde_entry_extras + return (dw_fde->pauth_key == AARCH64_PAUTH_KEY_B); +#else + return false; +#endif +} + /* SFrame Frame Row Entry (FRE) related functions. */ static void @@ -253,10 +264,12 @@ sframe_v1_set_fre_info (unsigned int base_reg, unsigned int num_offsets, /* SFrame (SFRAME_VERSION_1) set function info. */ static unsigned char -sframe_v1_set_func_info (unsigned int fde_type, unsigned int fre_type) +sframe_v1_set_func_info (unsigned int fde_type, unsigned int fre_type, + unsigned int pauth_key) { unsigned char func_info; func_info = SFRAME_V1_FUNC_INFO (fde_type, fre_type); + func_info = SFRAME_V1_FUNC_INFO_UPDATE_PAUTH_KEY (pauth_key, func_info); return func_info; } @@ -285,9 +298,10 @@ sframe_set_fre_info (unsigned int base_reg, unsigned int num_offsets, /* SFrame set func info. */ ATTRIBUTE_UNUSED static unsigned char -sframe_set_func_info (unsigned int fde_type, unsigned int fre_type) +sframe_set_func_info (unsigned int fde_type, unsigned int fre_type, + unsigned int pauth_key) { - return sframe_ver_ops.set_func_info (fde_type, fre_type); + return sframe_ver_ops.set_func_info (fde_type, fre_type, pauth_key); } /* Get the number of SFrame FDEs for the current file. */ @@ -544,6 +558,7 @@ output_sframe_funcdesc (symbolS *start_of_fre_section, expressionS exp; unsigned int addr_size; symbolS *dw_fde_start_addrS, *dw_fde_end_addrS; + unsigned int pauth_key; addr_size = SFRAME_RELOC_SIZE; dw_fde_start_addrS = get_dw_fde_start_addrS (sframe_fde->dw_fde); @@ -575,8 +590,11 @@ output_sframe_funcdesc (symbolS *start_of_fre_section, /* SFrame FDE function info. */ unsigned char func_info; + pauth_key = (get_dw_fde_pauth_b_key_p (sframe_fde->dw_fde) + ? SFRAME_AARCH64_PAUTH_KEY_B : SFRAME_AARCH64_PAUTH_KEY_A); func_info = sframe_set_func_info (SFRAME_FDE_TYPE_PCINC, - SFRAME_FRE_TYPE_ADDR4); + SFRAME_FRE_TYPE_ADDR4, + pauth_key); #if SFRAME_FRE_TYPE_SELECTION_OPT expressionS cexp; create_func_info_exp (&cexp, dw_fde_end_addrS, dw_fde_start_addrS, diff --git a/gas/gen-sframe.h b/gas/gen-sframe.h index 5d5702a..eb43c3a 100644 --- a/gas/gen-sframe.h +++ b/gas/gen-sframe.h @@ -146,7 +146,7 @@ struct sframe_version_ops unsigned char (*set_fre_info) (unsigned int, unsigned int, unsigned int, bool); /* set SFrame Func info. */ - unsigned char (*set_func_info) (unsigned int, unsigned int); + unsigned char (*set_func_info) (unsigned int, unsigned int, unsigned int); }; /* Generate SFrame unwind info and prepare contents for the output. diff --git a/gas/sframe-opt.c b/gas/sframe-opt.c index f08a424..cf7ca5c 100644 --- a/gas/sframe-opt.c +++ b/gas/sframe-opt.c @@ -95,6 +95,7 @@ sframe_convert_frag (fragS *frag) offsetT rest_of_data; uint8_t fde_type, fre_type; + uint8_t pauth_key; expressionS *exp; symbolS *dataS; @@ -116,6 +117,7 @@ sframe_convert_frag (fragS *frag) dataS = exp->X_add_symbol; rest_of_data = (symbol_get_value_expression(dataS))->X_add_number; fde_type = SFRAME_V1_FUNC_FDE_TYPE (rest_of_data); + pauth_key = SFRAME_V1_FUNC_PAUTH_KEY (rest_of_data); gas_assert (fde_type == SFRAME_FDE_TYPE_PCINC); /* Calculate the applicable fre_type. */ @@ -130,6 +132,7 @@ sframe_convert_frag (fragS *frag) /* Create the new function info. */ value = SFRAME_V1_FUNC_INFO (fde_type, fre_type); + value = SFRAME_V1_FUNC_INFO_UPDATE_PAUTH_KEY (pauth_key, value); frag->fr_literal[frag->fr_fix] = value; } -- cgit v1.1