aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthieu Longo <matthieu.longo@arm.com>2024-11-21 18:44:07 +0000
committerMatthieu Longo <matthieu.longo@arm.com>2025-01-14 10:53:21 +0000
commitb4c230fe2283cfe1a14426f68a1b76b05596a295 (patch)
tree0a7bfd1c78db64cabea42cd81f14d1661649646a
parent1956ad8d66b4dcbdda96073be208aeab99af4502 (diff)
downloadbinutils-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.c8
-rw-r--r--gas/testsuite/gas/aarch64/pac_ab_key.s4
-rw-r--r--gas/testsuite/gas/aarch64/pac_compat_cfi_window_save.d44
-rw-r--r--gas/testsuite/gas/aarch64/pac_compat_cfi_window_save.s20
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