Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Jon Burgess <jburgess777@gmail.com>
To: gdb-patches@sourceware.org
Subject: [RFC][PATCH] arm-tdep.c (arm_m_exception_cache): Handle stack switching to PSP during exception unwind.
Date: Sat, 20 Sep 2014 22:47:00 -0000	[thread overview]
Message-ID: <1411253227.22117.27.camel@shark.nightingale.homedns.org> (raw)

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



             reply	other threads:[~2014-09-20 22:47 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-09-20 22:47 Jon Burgess [this message]
2014-09-22 18:16 ` Sergio Durigan Junior
2014-09-23  5:30 ` Yao Qi
2014-09-23  8:38   ` Pedro Alves
2014-09-23 12:27     ` Yao Qi
2014-09-23 12:45       ` Pedro Alves
2015-05-07 18:00         ` Simon Schubert

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1411253227.22117.27.camel@shark.nightingale.homedns.org \
    --to=jburgess777@gmail.com \
    --cc=gdb-patches@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox