diff options
author | Sam Tebbs <sam.tebbs@arm.com> | 2018-12-05 18:27:23 +0000 |
---|---|---|
committer | Thomas Preud'homme <thomas.preudhomme@linaro.org> | 2018-12-05 18:30:08 +0000 |
commit | 3a67e1a6b4430374f3073e51bb19347d4c421cfe (patch) | |
tree | 6a75b3b1a27561b0e395dc69889051b71e67eff5 /gas/dw2gencfi.c | |
parent | 90af06793e9d391c0aa33994f21bba6971d084f7 (diff) | |
download | gdb-3a67e1a6b4430374f3073e51bb19347d4c421cfe.zip gdb-3a67e1a6b4430374f3073e51bb19347d4c421cfe.tar.gz gdb-3a67e1a6b4430374f3073e51bb19347d4c421cfe.tar.bz2 |
[aarch64] Add support for pointer authentication B key
Armv8.3-A has another key used in pointer authentication called the
B-key (other than the A-key that is already supported). In order for
stack unwinders to work it is necessary to be able to identify frames
that have been signed with the B-key rather than the A-key and it was
felt that keeping this as an augmentation character in the CIE was the
best bet. The DWARF extensions for ARM therefore propose to add a new
augmentation character 'B' to the CIE augmentation string and the
corresponding cfi directive ".cfi_b_key_frame". I've made the relevant
changes to GAS and LD to add support for B-key unwinding, which required
modifying LD to check for 'B' in the augmentation string, adding the
".cfi_b_key_frame" directive to GAS and adding a "pauth_key" field to
GAS's fde_entry and cie_entry structs.
The pointer authentication instructions will behave as NOPs on
architectures that don't support them, and so a check for the
architecture being assembled for is not necessary since there will be no
behavioural difference between augmentation strings with and without the
'B' character on such architectures.
2018-12-05 Sam Tebbs <sam.tebbs@arm.com>
bfd/
* elf-eh-frame.c (_bfd_elf_parse_eh_frame): Add check for 'B'.
gas/
* dw2gencfi.c (struct cie_entry): Add tc_cie_entry_extras invocation.
(alloc_fde_entry): 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 and
tc_cie_entry_init_extra invocation.
(frch_cfi_data, cfa_save_data): Move to dwgencfi.h.
* config/tc-aarch64.c (s_aarch64_cfi_b_key_frame): Declare.
(md_pseudo_table): Add "cfi_b_key_frame".
* config/tc-aarch64.h (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.h (struct fde_entry): Add tc_fde_entry_extras invocation.
(pointer_auth_key): Define.
(frch_cfi_data, cfa_save_data): Move from dwgencfi.c.
* doc/c-aarch64.texi (.cfi_b_key_frame): Add documentation.
* testsuite/gas/aarch64/(pac_ab_key.d, pac_ab_key.s): New file.
Diffstat (limited to 'gas/dw2gencfi.c')
-rw-r--r-- | gas/dw2gencfi.c | 22 |
1 files changed, 6 insertions, 16 deletions
diff --git a/gas/dw2gencfi.c b/gas/dw2gencfi.c index 4add173..ff5c0df 100644 --- a/gas/dw2gencfi.c +++ b/gas/dw2gencfi.c @@ -403,6 +403,7 @@ struct cie_entry unsigned char per_encoding; unsigned char lsda_encoding; expressionS personality; + enum pointer_auth_key pauth_key; struct cfi_insn_data *first, *last; }; @@ -414,22 +415,6 @@ static struct fde_entry **last_fde_data = &all_fde_data; /* List of CIEs so that they could be reused. */ static struct cie_entry *cie_root; -/* Stack of old CFI data, for save/restore. */ -struct cfa_save_data -{ - struct cfa_save_data *next; - offsetT cfa_offset; -}; - -/* Current open FDE entry. */ -struct frch_cfi_data -{ - struct fde_entry *cur_fde_data; - symbolS *last_address; - offsetT cur_cfa_offset; - struct cfa_save_data *cfa_save_stack; -}; - /* Construct a new FDE structure and add it to the end of the fde list. */ static struct fde_entry * @@ -448,6 +433,7 @@ 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; return fde; } @@ -1872,6 +1858,8 @@ 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'); } if (cie->signal_frame) out_one ('S'); @@ -2052,6 +2040,7 @@ select_cie_for_fde (struct fde_entry *fde, bfd_boolean eh_frame, if (CUR_SEG (cie) != CUR_SEG (fde)) continue; 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) @@ -2158,6 +2147,7 @@ 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; for (i = cie->first; i ; i = i->next) if (i->insn == DW_CFA_advance_loc |