aarch64: Fix pac-ret with unusual dwarf in libgcc unwinder [PR104689]
authorSzabolcs Nagy <szabolcs.nagy@arm.com>
Thu, 10 Feb 2022 17:42:56 +0000 (17:42 +0000)
committerSzabolcs Nagy <szabolcs.nagy@arm.com>
Wed, 25 May 2022 08:17:06 +0000 (09:17 +0100)
commit0d344b557604e966dc7f91739881f03e1f221efd
tree1f4c049fd1aea8937286c1d1d678b3fea1500985
parent768f49a20f467648c8e006e2431d0da3eab11846
aarch64: Fix pac-ret with unusual dwarf in libgcc unwinder [PR104689]

The RA_SIGN_STATE dwarf pseudo-register is normally only set using the
DW_CFA_AARCH64_negate_ra_state (== DW_CFA_window_save) operation which
toggles the return address signedness state (the default state is 0).
(It may be set by remember/restore_state CFI too, those save/restore
the state of all registers.)

However RA_SIGN_STATE can be set directly via DW_CFA_val_expression too.
GCC does not generate such CFI but some other compilers reportedly do.

Note: the toggle operation must not be mixed with other dwarf register
rule CFI within the same CIE and FDE.

In libgcc we assume REG_UNSAVED means the RA_STATE is set using toggle
operations, otherwise we assume its value is set by other CFI.

libgcc/ChangeLog:

PR target/104689
* config/aarch64/aarch64-unwind.h (aarch64_frob_update_context):
Handle the !REG_UNSAVED case.
* unwind-dw2.c (execute_cfa_program): Fail toggle if !REG_UNSAVED.

gcc/testsuite/ChangeLog:

PR target/104689
* gcc.target/aarch64/pr104689.c: New test.
gcc/testsuite/gcc.target/aarch64/pr104689.c [new file with mode: 0644]
libgcc/config/aarch64/aarch64-unwind.h
libgcc/unwind-dw2.c