dwarf2unwind : Force the CFA after remember/restore pairs [44107/48097].
authorIain Sandoe <iain@sandoe.co.uk>
Mon, 18 Jan 2021 20:09:10 +0000 (20:09 +0000)
committerIain Sandoe <iain@sandoe.co.uk>
Mon, 1 Mar 2021 19:37:09 +0000 (19:37 +0000)
commit491d5b3cf8216f9285a67aa213b9a66b0035137b
tree121a08ea63f1e22a97b0bf645de5432c8fe40c2f
parent4ed0a92f6cfc647e2ad8ceaa1e5709545c915465
dwarf2unwind : Force the CFA after remember/restore pairs [44107/48097].

This address one of the more long-standing and serious regressions
for Darwin.  GCC emits unwind code by default on the assumption that
the unwinder will be (of have the same capability) as the one in the
current libgcc_s.  For Darwin platforms, this is not the case - some
of them are based on the libgcc_s from GCC-4.2.1 and some are using
the unwinder provided by libunwind (part of the LLVM project). The
latter implementation has gradually adopted a section that deals with
GNU unwind.

The most serious problem for some of the platform versions is in
handling DW_CFA_remember/restore_state pairs.  The DWARF description
talks about these in terms of saving/restoring register rows; this is
what GCC originally did (and is what the unwinders do for the Darwin
versions based on libgcc_s).

However, in r118068, this was changed so that not only the registers
but also the current frame address expression were saved.  The unwind
code assumes that the unwinder will do this; some of Darwin's unwinders
do not, leading to lockups etc.  To date, the only solution has been
to replace the system libgcc_s with a newer one which is not a viable
solution for many end-users (since that means overwritting the one
provided with the system installation).

The fix here provides a target hook that allows the target to specify
that the CFA should be reinstated after a DW_CFA_restore.  This fixes
the issue (and also the closed WONTFIX of 44107).

(As a matter of record, it also fixes reported Java issues if
 backported to GCC-5).

gcc/ChangeLog:

PR target/44107
PR target/48097
* config/darwin-protos.h (darwin_should_restore_cfa_state): New.
* config/darwin.c (darwin_should_restore_cfa_state): New.
* config/darwin.h (TARGET_ASM_SHOULD_RESTORE_CFA_STATE): New.
* doc/tm.texi: Regenerated.
* doc/tm.texi.in: Document TARGET_ASM_SHOULD_RESTORE_CFA_STATE.
* dwarf2cfi.c (connect_traces): If the target requests, restore
the CFA expression after a DW_CFA_restore.
* target.def (TARGET_ASM_SHOULD_RESTORE_CFA_STATE): New hook.
gcc/config/darwin-protos.h
gcc/config/darwin.c
gcc/config/darwin.h
gcc/doc/tm.texi
gcc/doc/tm.texi.in
gcc/dwarf2cfi.c
gcc/target.def