diff options
author | Matthieu Longo <matthieu.longo@arm.com> | 2024-11-21 18:44:07 +0000 |
---|---|---|
committer | Matthieu Longo <matthieu.longo@arm.com> | 2025-01-14 10:53:21 +0000 |
commit | b4c230fe2283cfe1a14426f68a1b76b05596a295 (patch) | |
tree | 0a7bfd1c78db64cabea42cd81f14d1661649646a | |
parent | 1956ad8d66b4dcbdda96073be208aeab99af4502 (diff) | |
download | binutils-b4c230fe2283cfe1a14426f68a1b76b05596a295.zip binutils-b4c230fe2283cfe1a14426f68a1b76b05596a295.tar.gz binutils-b4c230fe2283cfe1a14426f68a1b76b05596a295.tar.bz2 |
aarch64: make explicit that CFI gnu_window_save is for Sparc, not AArch64
- add a detailed comment when parsing DW_CFA_GNU_window_save in SFrame to
explain why we are checking whether the targeted architecture is AArch64,
whereas this CFI is a Sparc extension.
- replace .cfi_gnu_window_save by .cfi_negate_ra_state in existing AArch64
DWARF tests as this is the preferred directive since GCC 15.
- add a new AArch64 test to check backward compatibility with old GCC
versions that emits .cfi_gnu_window_save.
Approved-by: Indu Bhagat <indu.bhagat@oracle.com>
Approved-by: Richard Earnshaw <richard.earnshaw@arm.com>
-rw-r--r-- | gas/gen-sframe.c | 8 | ||||
-rw-r--r-- | gas/testsuite/gas/aarch64/pac_ab_key.s | 4 | ||||
-rw-r--r-- | gas/testsuite/gas/aarch64/pac_compat_cfi_window_save.d | 44 | ||||
-rw-r--r-- | gas/testsuite/gas/aarch64/pac_compat_cfi_window_save.s | 20 |
4 files changed, 73 insertions, 3 deletions
diff --git a/gas/gen-sframe.c b/gas/gen-sframe.c index 71296f2..960c22e 100644 --- a/gas/gen-sframe.c +++ b/gas/gen-sframe.c @@ -1273,7 +1273,13 @@ sframe_xlate_do_aarch64_negate_ra_state (struct sframe_xlate_ctx *xlate_ctx, } /* Translate DW_CFA_GNU_window_save into SFrame context. - DW_CFA_AARCH64_negate_ra_state is multiplexed with DW_CFA_GNU_window_save. + DW_CFA_GNU_window_save is a DWARF Sparc extension, but is multiplexed with a + directive of DWARF AArch64 extension: DW_CFA_AARCH64_negate_ra_state. + The AArch64 backend of GCC 14 and older versions was emitting mistakenly the + Sparc CFI directive (.cfi_window_save). From GCC 15, the AArch64 backend + only emits .cfi_negate_ra_state. For backward compatibility, the handler for + .cfi_window_save needs to check whether the directive was used in a AArch64 + ABI context or not. Return SFRAME_XLATE_OK if success. */ static int diff --git a/gas/testsuite/gas/aarch64/pac_ab_key.s b/gas/testsuite/gas/aarch64/pac_ab_key.s index 4b328e7..3b81919 100644 --- a/gas/testsuite/gas/aarch64/pac_ab_key.s +++ b/gas/testsuite/gas/aarch64/pac_ab_key.s @@ -7,7 +7,7 @@ _Z5foo_av: .LFB0: .cfi_startproc hint 25 // paciasp - .cfi_window_save + .cfi_negate_ra_state stp x29, x30, [sp, -16]! .cfi_def_cfa_offset 16 .cfi_offset 29, -16 @@ -23,7 +23,7 @@ _Z5foo_bv: .cfi_startproc .cfi_b_key_frame hint 27 // pacibsp - .cfi_window_save + .cfi_negate_ra_state stp x29, x30, [sp, -16]! .cfi_def_cfa_offset 16 .cfi_offset 29, -16 diff --git a/gas/testsuite/gas/aarch64/pac_compat_cfi_window_save.d b/gas/testsuite/gas/aarch64/pac_compat_cfi_window_save.d new file mode 100644 index 0000000..8e59086 --- /dev/null +++ b/gas/testsuite/gas/aarch64/pac_compat_cfi_window_save.d @@ -0,0 +1,44 @@ +#objdump: --dwarf=frames +# This test is only valid on ELF based ports. +#notarget: *-*-*coff *-*-pe *-*-wince *-*-*aout* *-*-netbsd + +## ARMv8.3 adds support for a new security feature named Pointer Authentication. +## The main idea behind this is to use the unused bits in the pointer values. +## Each pointer is patched with a PAC before writing to memory, and is verified +## before using it. +## When the pointers are mangled, the stack trace generator needs to know so it +## can mask off the PAC from the pointer value to recover the return address, +## and conversely, skip doing so if the pointers are not mangled. +## +## .cfi_negate_ra_state CFI directive is usually used to convey this information. +## .cfi_negate_ra_state and .cfi_window_save are both in the processor-specific +## numbering space, but use the same code value in the dwarf tables. +## In GCC 14 and older, the Sparc DWARF extension .cfi_window_save is emitted +## instead of .cfi_negate_ra_state, but it mapped to the same value. GCC 15 fixed +## this naming issue and there is no change to the object file created when the +## source is assembled. Nevertheless the support for the SPARC directive is +## preserved in binutils for backward compatibility with existing GCC releases, +## hence this test. + +.+: file .+ + +Contents of the .eh_frame section: + +0+ 0+10 0+ CIE + Version: 1 + Augmentation: "zR" + Code alignment factor: 4 + Data alignment factor: -8 + Return address column: 30 + Augmentation data: 1b + DW_CFA_def_cfa: r31 \(sp\) ofs 0 + +0+14 0+18 0+18 FDE cie=0+ pc=0+\.\.0+8 + DW_CFA_advance_loc: 4 to 0+4 + DW_CFA_AARCH64_negate_ra_state + DW_CFA_advance_loc: 4 to 0+8 + DW_CFA_def_cfa_offset: 16 + DW_CFA_offset: r29 \(x29\) at cfa-16 + DW_CFA_offset: r30 \(x30\) at cfa-8 + DW_CFA_nop + DW_CFA_nop diff --git a/gas/testsuite/gas/aarch64/pac_compat_cfi_window_save.s b/gas/testsuite/gas/aarch64/pac_compat_cfi_window_save.s new file mode 100644 index 0000000..92a54f3 --- /dev/null +++ b/gas/testsuite/gas/aarch64/pac_compat_cfi_window_save.s @@ -0,0 +1,20 @@ + .arch armv8-a + .text + .align 2 + .global _Z5foo_av + .type _Z5foo_av, %function +_Z5foo_av: +.LFB0: + .cfi_startproc + hint 25 // paciasp + .cfi_window_save // really .cfi_negate_ra_state + stp x29, x30, [sp, -16]! + .cfi_def_cfa_offset 16 + .cfi_offset 29, -16 + .cfi_offset 30, -8 + .cfi_endproc +.LFE0: + .size _Z5foo_av, .-_Z5foo_av + .align 2 + .global _Z5foo_bv + .type _Z5foo_bv, %function |