From c97f3a7dc230dab0877d0c27b84eb06132cf7bf8 Mon Sep 17 00:00:00 2001 From: Doug Rupp Date: Thu, 14 Apr 2022 10:59:37 -0700 Subject: [PATCH] [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. --- gcc/ada/init.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) 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); } -- 2.47.2