diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ada/init.c | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/gcc/ada/init.c b/gcc/ada/init.c index 89f16a1..7322a54 100644 --- a/gcc/ada/init.c +++ b/gcc/ada/init.c @@ -2560,6 +2560,29 @@ __gnat_install_handler (void) #include <errno.h> #include "sigtramp.h" +#if defined (__ARMEL__) && !defined (__aarch64__) + +/* ARM-QNX case with arm unwinding exceptions */ +#define HAVE_GNAT_ADJUST_CONTEXT_FOR_RAISE + +#include <ucontext.h> +#include <arm/cpu.h> +#include <stdint.h> + +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); } |