From: Doug Rupp Date: Thu, 14 Apr 2022 17:59:37 +0000 (-0700) Subject: [Ada] arm-qnx-7.1: unwind goes wrong after regs restore X-Git-Tag: basepoints/gcc-14~6326 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=c97f3a7dc230dab0877d0c27b84eb06132cf7bf8;p=thirdparty%2Fgcc.git [Ada] arm-qnx-7.1: unwind goes wrong after regs restore The usual increment of the pc to pc+2 for ARM is needed. gcc/ada/ * init.c (QNX): __gnat_adjust_context_for_raise: New implementation for arm-qnx. --- diff --git a/gcc/ada/init.c b/gcc/ada/init.c index 89f16a176d3..7322a54a4da 100644 --- a/gcc/ada/init.c +++ b/gcc/ada/init.c @@ -2560,6 +2560,29 @@ __gnat_install_handler (void) #include #include "sigtramp.h" +#if defined (__ARMEL__) && !defined (__aarch64__) + +/* ARM-QNX case with arm unwinding exceptions */ +#define HAVE_GNAT_ADJUST_CONTEXT_FOR_RAISE + +#include +#include +#include + +void +__gnat_adjust_context_for_raise (int signo ATTRIBUTE_UNUSED, + void *sc ATTRIBUTE_UNUSED) +{ + /* In case of ARM exceptions, the registers context have the PC pointing + to the instruction that raised the signal. However the unwinder expects + the instruction to be in the range [PC+2,PC+3]. */ + uintptr_t *pc_addr; + mcontext_t *mcontext = &((ucontext_t *) sc)->uc_mcontext; + pc_addr = (uintptr_t *)&mcontext->cpu.gpr [ARM_REG_PC]; + *pc_addr += 2; +} +#endif /* ARMEL */ + void __gnat_map_signal (int sig, siginfo_t *si ATTRIBUTE_UNUSED, @@ -2597,6 +2620,13 @@ __gnat_map_signal (int sig, static void __gnat_error_handler (int sig, siginfo_t *si, void *ucontext) { +#ifdef HAVE_GNAT_ADJUST_CONTEXT_FOR_RAISE + /* We need to sometimes to adjust the PC in case of signals so that it + doesn't reference the exception that actually raised the signal but the + instruction before it. */ + __gnat_adjust_context_for_raise (sig, ucontext); +#endif + __gnat_sigtramp (sig, (void *) si, (void *) ucontext, (__sigtramphandler_t *)&__gnat_map_signal); }