[Ada] arm-qnx-7.1: unwind goes wrong after regs restore
authorDoug Rupp <rupp@adacore.com>
Fri, 6 May 2022 22:28:49 +0000 (15:28 -0700)
committerPierre-Marie de Rodat <derodat@adacore.com>
Wed, 1 Jun 2022 08:43:19 +0000 (08:43 +0000)
Bump the pc +3 total for Thumb mode, the same calculation that as is
done for arm-linux.

gcc/ada/

* init.c (__gnat_adjust_context_for_raise) [QNX][__thumb2__]: Bump
the pc an extra byte.

gcc/ada/init.c

index 7322a54..cfae740 100644 (file)
@@ -2579,7 +2579,17 @@ __gnat_adjust_context_for_raise (int signo ATTRIBUTE_UNUSED,
   uintptr_t *pc_addr;
   mcontext_t *mcontext = &((ucontext_t *) sc)->uc_mcontext;
   pc_addr = (uintptr_t *)&mcontext->cpu.gpr [ARM_REG_PC];
+
+  /* ARM Bump has to be an even number because of odd/even architecture.  */
   *pc_addr += 2;
+#ifdef __thumb2__
+  /* For thumb, the return address must have the low order bit set, otherwise
+     the unwinder will reset to "arm" mode upon return.  As long as the
+     compilation unit containing the landing pad is compiled with the same
+     mode (arm vs thumb) as the signaling compilation unit, this works.  */
+  if (mcontext->cpu.spsr & ARM_CPSR_T)
+    *pc_addr += 1;
+#endif
 }
 #endif /* ARMEL */