diff options
author | Matthieu Longo <matthieu.longo@arm.com> | 2024-09-23 15:35:07 +0100 |
---|---|---|
committer | Tamar Christina <tamar.christina@arm.com> | 2024-09-23 15:37:45 +0100 |
commit | 2b7971448f122317ed012586f9f73ccc0537deb2 (patch) | |
tree | d86887fcc2426607fb129b2fc6896106c28ef770 | |
parent | fb475d3f25943beffac8e9c0c78247bad75287a1 (diff) | |
download | gcc-2b7971448f122317ed012586f9f73ccc0537deb2.zip gcc-2b7971448f122317ed012586f9f73ccc0537deb2.tar.gz gcc-2b7971448f122317ed012586f9f73ccc0537deb2.tar.bz2 |
dwarf2: store the RA state in CFI row
On AArch64, the RA state informs the unwinder whether the return address
is mangled and how, or not. This information is encoded in a boolean in
the CFI row. This binary approach prevents from expressing more complex
configuration, as it is the case with PAuth_LR introduced in Armv9.5-A.
This patch addresses this limitation by replacing the boolean by an enum.
gcc/ChangeLog:
* dwarf2cfi.cc
(struct dw_cfi_row): Declare a new enum type to replace ra_mangled.
(cfi_row_equal_p): Use ra_state instead of ra_mangled.
(dwarf2out_frame_debug_cfa_negate_ra_state): Same.
(change_cfi_row): Same.
-rw-r--r-- | gcc/dwarf2cfi.cc | 24 |
1 files changed, 18 insertions, 6 deletions
diff --git a/gcc/dwarf2cfi.cc b/gcc/dwarf2cfi.cc index f8d19d5..1b94185 100644 --- a/gcc/dwarf2cfi.cc +++ b/gcc/dwarf2cfi.cc @@ -57,6 +57,15 @@ along with GCC; see the file COPYING3. If not see #define DEFAULT_INCOMING_FRAME_SP_OFFSET INCOMING_FRAME_SP_OFFSET #endif + +/* Signing method used for return address authentication. + (AArch64 extension) */ +typedef enum +{ + ra_no_signing = 0x0, + ra_signing_sp = 0x1, +} ra_signing_method_t; + /* A collected description of an entire row of the abstract CFI table. */ struct GTY(()) dw_cfi_row { @@ -74,8 +83,8 @@ struct GTY(()) dw_cfi_row bool window_save; /* AArch64 extension for DW_CFA_AARCH64_negate_ra_state. - True if the return address is in a mangled state. */ - bool ra_mangled; + Enum which stores the return address state. */ + ra_signing_method_t ra_state; }; /* The caller's ORIG_REG is saved in SAVED_IN_REG. */ @@ -857,7 +866,7 @@ cfi_row_equal_p (dw_cfi_row *a, dw_cfi_row *b) if (a->window_save != b->window_save) return false; - if (a->ra_mangled != b->ra_mangled) + if (a->ra_state != b->ra_state) return false; return true; @@ -1554,8 +1563,11 @@ dwarf2out_frame_debug_cfa_negate_ra_state (void) { dw_cfi_ref cfi = new_cfi (); cfi->dw_cfi_opc = DW_CFA_AARCH64_negate_ra_state; + cur_row->ra_state + = (cur_row->ra_state == ra_no_signing + ? ra_signing_sp + : ra_no_signing); add_cfi (cfi); - cur_row->ra_mangled = !cur_row->ra_mangled; } /* Record call frame debugging information for an expression EXPR, @@ -2412,12 +2424,12 @@ change_cfi_row (dw_cfi_row *old_row, dw_cfi_row *new_row) { dw_cfi_ref cfi = new_cfi (); - gcc_assert (!old_row->ra_mangled && !new_row->ra_mangled); + gcc_assert (!old_row->ra_state && !new_row->ra_state); cfi->dw_cfi_opc = DW_CFA_GNU_window_save; add_cfi (cfi); } - if (old_row->ra_mangled != new_row->ra_mangled) + if (old_row->ra_state != new_row->ra_state) { dw_cfi_ref cfi = new_cfi (); |