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]

[RFC][PATCH] arm-tdep.c (arm_m_exception_cache): Handle stack switching to PSP during exception unwind.


The current GDB code sometimes unwinds the exception stack incorrectly
on a Cortex-M3 based CPU (Atmel ATSAM3X8E). The problem is that the
current stack unwinding code does not take into account that the stack
pointer may switch from the main stack pointer (MSP) to the process
stack pointer (PSP) when the exception returns. 

The result is that the code displayed as executing at the time of the
exception is incorrect:

(gdb) bt
#0  delayMS (millis=300) at FreeRTOS_ARM/FreeRTOS_ARM.c:17
#1  errorBlink (n=n@entry=1) at FreeRTOS_ARM/FreeRTOS_ARM.c:32
#2  0x00085cd4 in HardFault_Handler () at FreeRTOS_ARM/FreeRTOS_ARM.c:44
#3  <signal handler called>
#4  0x0008684e in prvPortStartFirstTask () at FreeRTOS_ARM/utility/port.c:277
#5  0x00086a38 in xPortStartScheduler () at FreeRTOS_ARM/utility/port.c:356
#6  0xa5a5a5a4 in ?? ()

With the patch applied the code which accessed the bad pointer to
trigger the exception is displayed instead:

(gdb) bt
#0  delayMS (millis=300) at FreeRTOS_ARM/FreeRTOS_ARM.c:17
#1  errorBlink (n=n@entry=1) at FreeRTOS_ARM/FreeRTOS_ARM.c:32
#2  0x00085cd4 in HardFault_Handler () at FreeRTOS_ARM/FreeRTOS_ARM.c:44
#3  <signal handler called>
#4  xQueueGenericReceive (xQueue=0xa5a5a5a5, pvBuffer=0x20082856, xTicksToWait=4294967295, xJustPeeking=0)
    at FreeRTOS_ARM/utility/queue.c:1193
#5  0x00085214 in BuzzerTask::task (this=0x2007f5c0) at BuzzerTask.cpp:68
#6  0x000818ec in Task::taskCaller (this=0x2007f5c0) at Task.cpp:78
#7  0x0008193e in Task::_task (self=<optimized out>) at Task.cpp:87
#8  0x000868bc in ulPortSetInterruptMask () at FreeRTOS_ARM/utility/port.c:423


I do not know the best way to access the PSP register to find the
process stack pointer. It looks like that this has to go via the target
description because it is not included in the default register list. In
the patch I follow the mechanism that GDB uses to lookup the register
number during "p $psp". 

This patch has only been tested on this single target running FreeRTOS.
I used an Olimex ARM-USB-TINY-H with OpenOCD to attach to the device.

This my first GDB patch submission and I have not been through this FSF
copyright assignment process.



2014-09-20  Jon Burgess  <jburgess777@gmail.com>

        * arm-tdep.c (arm_m_exception_cache): Handle stack switching
       to PSP during exception unwind.


diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
index 5cdfc5b..66a0ae8 100644
--- a/gdb/arm-tdep.c
+++ b/gdb/arm-tdep.c
@@ -3010,6 +3010,7 @@ arm_m_exception_cache (struct frame_info
*this_frame)
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   struct arm_prologue_cache *cache;
+  CORE_ADDR this_pc = get_frame_pc (this_frame);
   CORE_ADDR unwound_sp;
   LONGEST xpsr;
 
@@ -3019,6 +3020,24 @@ arm_m_exception_cache (struct frame_info
*this_frame)
   unwound_sp = get_frame_register_unsigned (this_frame,
                                            ARM_SP_REGNUM);
 
+  /* The EXC_RETURN address indicates what type of transition
+     the CPU makes when returning from the exception. A value
+     of 0xfffffffd causes the stack pointer to switch from
+     MSP to PSP. */
+  if (this_pc == 0xfffffffd) {
+    int pspreg;
+    struct regcache *regcache;
+    struct value *pspval;
+
+    pspreg = user_reg_map_name_to_regnum (gdbarch, "psp", 3);
+    gdb_assert (pspreg != -1);
+
+    regcache = get_current_regcache ();
+    pspval = regcache_cooked_read_value (regcache, pspreg);
+    if (pspval && !value_lazy (pspval))
+      unwound_sp = value_as_address (pspval);
+  }
+
   /* The hardware saves eight 32-bit words, comprising xPSR,
      ReturnAddress, LR (R14), R12, R3, R2, R1, R0.  See details in
      "B1.5.6 Exception entry behavior" in



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