This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Re: [PATCH] Fix exception unwinding for ARM Cortex-M


Hi, I'm back from the dead.

Seriously though, I was a bit too busy at work to pursue on this and I didn't have a clear idea of where to start after the comments. Moreover, as the patch did "just work" at my workplace, it was a bit difficult to justify spending a lot more time digging information about target descriptions, how to determine what features are present on target, etc.

So thanks to push toward the progress of this issue, apparently with your mail subject you successfully brought people that gives more specific guidance to get this done.

Indeed, the patch looks really close to what I've done, to the point that I can see that, aside from a small refactoring, the changes between our patches are mainly variable name changes and added comments. You really wrote your patch from scratch? You've got rid of the various calls to `user_reg_map_name_to_regnum', though, which is nice.

> Cortex-M has two stack pointers: MSP (Main Stack Pointer) and PSP (Process Stack Pointer). > This is not handled when GDB tries to backtrace in the exception stack unwinder. > Meaning for eg. Cortex-M4F its not possible to get any call-stack backtrace if setting a breakpoint in ISR, and floating-point variable was used.

Actually, the info here is inaccurate: FPU context stacking and the MSP/PSP switch are two unrelated concepts. Meaning, you can fix the code to deal with the PSP, but it still won't handle FPU register unstacking.

> This patch was inspired by the great work done by James-Adam Renquinha Henri, submitted April this year.
Thanks :)

> The next thing would then be to also add FPU context control reg FPCCR, which is needed for retrieving info on the FPU lazy stacking. > Though its complicated I think and I will try to investigate an 'arm-m-fpu.xml' profile further, if this is solution perhaps.

It indeed is just a bit more complicated. Let me summarize what needs to be done. Have the ARMv7-M Architecture Reference Manual handy, see B1.5.7.

- Check if lazy stacking is enabled (FPCCR.LSPEN == 1). If it's not, the case is uncomplicated, registers are stacked as usual - If lazy stacking is active (FPCCR.LSACT == 1), the extended stack has space reserved for the FPU registers (S0-S15, FPSCR), but there are not stacked, they are still in FPU registers unmodified.

So that adds more random fetches from "memory" of the target, because these are memory-mapped.

ARM gives some example scenarios with chronograms of some important bits with stacking information [1].

> ChangeLog entry should cover what do you change on the function level.
> Please read https://sourceware.org/gdb/wiki/ContributionChecklist

If only I knew that checklist! I searched for something like this, but maybe it didn't use the correct search terms, I didn't find it.

[1] http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dai0298a/DAFGGBJD.html

James-Adam Renquinha Henri, Ing. jr
Ingénieur d'application
CIMEQ INC.


Le 2016-08-03 à 06:56, Fredrik Hederstierna a écrit :
Hi Yao,

thanks for reviewing, I attach here updated patch.

I have FSF assignment papers for GCC from December 2005, maybe needs separate assignment for GDB,
so I have now sent in application to FSF for GDB assignment as well.

gdb/ChangeLog:

2016-08-03  Fredrik Hederstierna  <fredrik.hederstierna@verisure.com>

       * arm-tdep.c (arm_m_addr_is_magic): New function.
       (arm_addr_bits_remove)
       (arm_m_exception_unwind_sniffer):  Check correct EXC_RETURN values.

diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
index d2661cb..1d154cc 100644
--- a/gdb/arm-tdep.c
+++ b/gdb/arm-tdep.c
@@ -464,6 +464,61 @@ arm_pc_is_thumb (struct gdbarch *gdbarch, CORE_ADDR memaddr)
   return 0;
 }

+/* Determine if the address specified equals any of
+  these magic return values, called EXC_RETURN, defined
+  by the ARM v6-M and v7-M architectures.
+
+  From ARMv6-M Reference Manual B1.5.8
+  Table B1-5 Exception return behavior
+
+  EXC_RETURN    Return To        Return Stack
+  0xFFFFFFF1    Handler mode     Main
+  0xFFFFFFF9    Thread mode      Main
+  0xFFFFFFFD    Thread mode      Process
+
+  From ARMv7-M Reference Manual B1.5.8
+  Table B1-8 EXC_RETURN definition of exception return behavior, no FP
+
+  EXC_RETURN    Return To        Return Stack
+  0xFFFFFFF1    Handler mode     Main
+  0xFFFFFFF9    Thread mode      Main
+  0xFFFFFFFD    Thread mode      Process
+
+  Table B1-9 EXC_RETURN definition of exception return behavior, with FP
+
+  EXC_RETURN    Return To        Return Stack    Frame Type
+  0xFFFFFFE1    Handler mode     Main            Extended
+  0xFFFFFFE9    Thread mode      Main            Extended
+  0xFFFFFFED    Thread mode      Process         Extended
+  0xFFFFFFF1    Handler mode     Main            Basic
+  0xFFFFFFF9    Thread mode      Main            Basic
+  0xFFFFFFFD    Thread mode      Process         Basic
+
+  For more details see "B1.5.8 Exception return behavior"
+  in both ARMv6-M and ARMv7-M Architecture Reference Manuals.  */
+
+static int
+arm_m_addr_is_magic (CORE_ADDR addr)
+{
+  switch (addr)
+    {
+      /* Values from Tables in B1.5.8 the EXC_RETURN definitions of
+         the exception return behavior.  */
+      case 0xffffffe1:
+      case 0xffffffe9:
+      case 0xffffffed:
+      case 0xfffffff1:
+      case 0xfffffff9:
+      case 0xfffffffd:
+        /* Address is magic.  */
+        return 1;
+
+      default:
+        /* Address is not magic.  */
+        return 0;
+    }
+}
+
 /* Remove useless bits from addresses in a running program.  */
 static CORE_ADDR
 arm_addr_bits_remove (struct gdbarch *gdbarch, CORE_ADDR val)
@@ -471,7 +526,7 @@ arm_addr_bits_remove (struct gdbarch *gdbarch, CORE_ADDR val)
   /* On M-profile devices, do not strip the low bit from EXC_RETURN
      (the magic exception return address).  */
   if (gdbarch_tdep (gdbarch)->is_m
-      && (val & 0xfffffff0) =0xfffffff0)
+      && arm_m_addr_is_magic (val))
     return val;

   if (arm_apcs_32)
@@ -2990,14 +3045,8 @@ arm_m_exception_unwind_sniffer (const struct frame_unwind *self,
   /* No need to check is_m; this sniffer is only registered for
      M-profile architectures.  */

-  /* Exception frames return to one of these magic PCs.  Other values
-     are not defined as of v7-M.  See details in "B1.5.8 Exception
-     return behavior" in "ARMv7-M Architecture Reference Manual".  */
-  if (this_pc =0xfffffff1 || this_pc == 0xfffffff9
-      || this_pc =0xfffffffd)
-    return 1;
-
-  return 0;
+  /* Check if exception frame returns to a magic PC value.  */
+  return arm_m_addr_is_magic (this_pc);
 }

 /* Frame unwinder for M-profile exceptions.  */
--



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]