]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
2007-04-18 Daniel Jacobowitz <dan@codesourcery.com>
authorMichael Snyder <msnyder@vmware.com>
Tue, 10 Jun 2008 18:06:04 +0000 (18:06 +0000)
committerMichael Snyder <msnyder@vmware.com>
Tue, 10 Jun 2008 18:06:04 +0000 (18:06 +0000)
* arm-tdep.c (arm_scan_epilogue): New.
(arm_make_prologue_cache): Use it.
(arm_epilogue_unwind_sniffer): New.
(arm_gdbarch_init): Register it.

gdb/ChangeLog
gdb/arm-tdep.c

index 3deec46401bd9a3153acd683f4ed3a23fbc361b1..8a9b31ae3c48762a083c9257f5c1541b376d2184 100644 (file)
        * Makefile.in (reverse.c): New file.
        * reverse.c: New file.  User interface for reverse execution.
 
+2007-04-18  Daniel Jacobowitz  <dan@codesourcery.com>
+
+       * arm-tdep.c (arm_scan_epilogue): New.
+       (arm_make_prologue_cache): Use it.
+       (arm_epilogue_unwind_sniffer): New.
+       (arm_gdbarch_init): Register it.
+
 2008-06-09  Doug Evans  <dje@google.com>
 
        * remote.c (remote_wait): Include beginning of malformed packet
index fd732a87e4510a0be2a26189f45a364c41aa656b..0d4d1fe55b0f570200c9c3c2375d2b5ecb361ceb 100644 (file)
@@ -1011,6 +1011,84 @@ arm_scan_prologue (struct frame_info *this_frame,
   do_cleanups (back_to);
 }
 
+/* This function tries to guess whether we are in the epilogue of an
+   ARM function.  We need to detect whether the stack frame has
+   already been destroyed - if it has, then neither the prologue
+   scanner nor GCC's unwind tables will be valid.  This is very hokey
+   and generally unsafe.  */
+
+static int
+arm_scan_epilogue (struct frame_info *next_frame,
+                  struct arm_prologue_cache *cache)
+{
+  unsigned int insn;
+  gdb_byte buf[4];
+  CORE_ADDR prev_pc = frame_pc_unwind (next_frame);
+
+  /* Assume there is no frame until proven otherwise.  */
+  if (cache != NULL)
+    {
+      cache->framereg = ARM_SP_REGNUM;
+      cache->framesize = 0;
+      cache->frameoffset = 0;
+    }
+
+  /* Check for Thumb epilogue.  */
+  if (arm_pc_is_thumb (prev_pc))
+    /* Not yet implemented.  */
+    return 0;
+
+  if (target_read_memory (prev_pc, buf, 4) != 0)
+    return 0;
+  insn = extract_unsigned_integer (buf, 4);
+
+  if (insn == 0xe12fff1e) /* bx lr */
+    /* If this is a return, we have no frame left and no saved
+       registers.  */
+    return 1;
+
+  return 0;
+}
+
+/* This function tries to guess whether we are in the epilogue of an
+   ARM function.  We need to detect whether the stack frame has
+   already been destroyed - if it has, then neither the prologue
+   scanner nor GCC's unwind tables will be valid.  This is very hokey
+   and generally unsafe.  */
+
+static int
+arm_scan_epilogue (struct frame_info *next_frame,
+                  struct arm_prologue_cache *cache)
+{
+  unsigned int insn;
+  gdb_byte buf[4];
+  CORE_ADDR prev_pc = frame_pc_unwind (next_frame);
+
+  /* Assume there is no frame until proven otherwise.  */
+  if (cache != NULL)
+    {
+      cache->framereg = ARM_SP_REGNUM;
+      cache->framesize = 0;
+      cache->frameoffset = 0;
+    }
+
+  /* Check for Thumb epilogue.  */
+  if (arm_pc_is_thumb (prev_pc))
+    /* Not yet implemented.  */
+    return 0;
+
+  if (target_read_memory (prev_pc, buf, 4) != 0)
+    return 0;
+  insn = extract_unsigned_integer (buf, 4);
+
+  if (insn == 0xe12fff1e) /* bx lr */
+    /* If this is a return, we have no frame left and no saved
+       registers.  */
+    return 1;
+
+  return 0;
+}
+
 static struct arm_prologue_cache *
 arm_make_prologue_cache (struct frame_info *this_frame)
 {
@@ -1132,6 +1210,24 @@ struct frame_unwind arm_prologue_unwind = {
   default_frame_sniffer
 };
 
+static const struct frame_unwind *
+arm_epilogue_unwind_sniffer (struct frame_info *next_frame)
+{
+  if (arm_scan_epilogue (next_frame, NULL))
+    return &arm_prologue_unwind;
+  else
+    return NULL;
+}
+
+static const struct frame_unwind *
+arm_epilogue_unwind_sniffer (struct frame_info *next_frame)
+{
+  if (arm_scan_epilogue (next_frame, NULL))
+    return &arm_prologue_unwind;
+  else
+    return NULL;
+}
+
 static struct arm_prologue_cache *
 arm_make_stub_cache (struct frame_info *this_frame)
 {