diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 0c2ae029392..0c1034087ea 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2020-04-21 Szabolcs Nagy + + PR target/94514 + * g++.target/aarch64/pr94514.C: New test. + * gcc.target/aarch64/pr94514.c: New test. + 2020-04-21 Richard Sandiford PR tree-optimization/94683 diff --git a/gcc/testsuite/g++.target/aarch64/pr94514.C b/gcc/testsuite/g++.target/aarch64/pr94514.C new file mode 100644 index 00000000000..2a8c949ba30 --- /dev/null +++ b/gcc/testsuite/g++.target/aarch64/pr94514.C @@ -0,0 +1,26 @@ +/* PR target/94514. Unwind across mixed pac-ret and non-pac-ret frames. */ +/* { dg-do run } */ + +__attribute__((noinline, target("branch-protection=pac-ret"))) +static void do_throw (void) +{ + throw 42; + __builtin_abort (); +} + +__attribute__((noinline, target("branch-protection=none"))) +static void no_pac_ret (void) +{ + do_throw (); + __builtin_abort (); +} + +int main () +{ + try { + no_pac_ret (); + } catch (...) { + return 0; + } + __builtin_abort (); +} diff --git a/gcc/testsuite/gcc.target/aarch64/pr94514.c b/gcc/testsuite/gcc.target/aarch64/pr94514.c new file mode 100644 index 00000000000..bbbf5a6b0b3 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/pr94514.c @@ -0,0 +1,76 @@ +/* PR target/94514. Unwind across mixed pac-ret and non-pac-ret frames. */ +/* { dg-do run } */ +/* { dg-options "-fexceptions -O2" } */ + +#include +#include +#include + +#define die() \ + do { \ + printf ("%s:%d: reached unexpectedly.\n", __FILE__, __LINE__); \ + fflush (stdout); \ + abort (); \ + } while (0) + +static struct _Unwind_Exception exc; + +static _Unwind_Reason_Code +force_unwind_stop (int version, _Unwind_Action actions, + _Unwind_Exception_Class exc_class, + struct _Unwind_Exception *exc_obj, + struct _Unwind_Context *context, + void *stop_parameter) +{ + printf ("%s: CFA: %p PC: %p actions: %d\n", + __func__, + (void *)_Unwind_GetCFA (context), + (void *)_Unwind_GetIP (context), + (int)actions); + if (actions & _UA_END_OF_STACK) + die (); + return _URC_NO_REASON; +} + +static void force_unwind (void) +{ +#ifndef __USING_SJLJ_EXCEPTIONS__ + _Unwind_ForcedUnwind (&exc, force_unwind_stop, 0); +#else + _Unwind_SjLj_ForcedUnwind (&exc, force_unwind_stop, 0); +#endif +} + +__attribute__((noinline, target("branch-protection=pac-ret"))) +static void f2_pac_ret (void) +{ + force_unwind (); + die (); +} + +__attribute__((noinline, target("branch-protection=none"))) +static void f1_no_pac_ret (void) +{ + f2_pac_ret (); + die (); +} + +__attribute__((noinline, target("branch-protection=pac-ret"))) +static void f0_pac_ret (void) +{ + f1_no_pac_ret (); + die (); +} + +static void cleanup_handler (void *p) +{ + printf ("%s: Success.\n", __func__); + exit (0); +} + +int main () +{ + char dummy __attribute__((cleanup (cleanup_handler))); + f0_pac_ret (); + die (); +} diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog index d66f76fdd01..da419ff4b0a 100644 --- a/libgcc/ChangeLog +++ b/libgcc/ChangeLog @@ -1,3 +1,9 @@ +2020-04-21 Szabolcs Nagy + + PR target/94514 + * config/aarch64/aarch64-unwind.h (aarch64_frob_update_context): + Update context->flags accroding to the frame state. + 2020-04-19 Uroš Bizjak * config/i386/sfp-exceptions.c (__sfp_handle_exceptions) [__SSE_MATH__]: diff --git a/libgcc/config/aarch64/aarch64-unwind.h b/libgcc/config/aarch64/aarch64-unwind.h index 4c8790bae67..ed84a96db41 100644 --- a/libgcc/config/aarch64/aarch64-unwind.h +++ b/libgcc/config/aarch64/aarch64-unwind.h @@ -104,6 +104,8 @@ aarch64_frob_update_context (struct _Unwind_Context *context, if (fs->regs.reg[DWARF_REGNUM_AARCH64_RA_STATE].loc.offset & 0x1) /* The flag is used for re-authenticating EH handler's address. */ context->flags |= RA_SIGNED_BIT; + else + context->flags &= ~RA_SIGNED_BIT; return; }