Add new devices x1122 x1132 emulation.
[deliverable/binutils-gdb.git] / gdb / dummy-frame.c
index 99d388df92a911b335908d9dac471907ffb38031..5b638306fd3956ed7733e96f0308e92d7e3fecc8 100644 (file)
@@ -28,6 +28,7 @@
 #include "frame.h"
 #include "inferior.h"
 #include "gdb_assert.h"
+#include "frame-unwind.h"
 
 /* Dummy frame.  This saves the processor state just prior to setting
    up the inferior function call.  Older targets save the registers
@@ -269,8 +270,48 @@ generic_pop_current_frame (void (*popper) (struct frame_info * frame))
     (*popper) (frame);
 }
 
-/* Function: pop_dummy_frame
-   Restore the machine state from a saved dummy stack frame. */
+/* Discard the innermost dummy frame from the dummy frame stack
+   (passed in as a parameter).  */
+
+static void
+discard_innermost_dummy (struct dummy_frame **stack)
+{
+  struct dummy_frame *tbd = (*stack);
+  (*stack) = (*stack)->next;
+  regcache_xfree (tbd->regcache);
+  xfree (tbd);
+}
+
+/* Function: dummy_frame_pop.  Restore the machine state from a saved
+   dummy stack frame. */
+
+static void
+dummy_frame_pop (struct frame_info *fi, void **cache,
+                struct regcache *regcache)
+{
+  struct dummy_frame *dummy = cached_find_dummy_frame (fi, cache);
+
+  /* If it isn't, what are we even doing here?  */
+  gdb_assert (get_frame_type (fi) == DUMMY_FRAME);
+
+  if (dummy == NULL)
+    error ("Can't pop dummy frame!");
+
+  /* Discard all dummy frames up-to but not including this one.  */
+  while (dummy_frame_stack != dummy)
+    discard_innermost_dummy (&dummy_frame_stack);
+
+  /* Restore this one.  */
+  regcache_cpy (regcache, dummy->regcache);
+  flush_cached_frames ();
+
+  /* Now discard it.  */
+  discard_innermost_dummy (&dummy_frame_stack);
+
+  /* Note: target changed would be better.  Registers, memory and
+     frame are all invalid.  */
+  flush_cached_frames ();
+}
 
 void
 generic_pop_dummy_frame (void)
@@ -282,12 +323,10 @@ generic_pop_dummy_frame (void)
 
   if (!dummy_frame)
     error ("Can't pop dummy frame!");
-  dummy_frame_stack = dummy_frame->next;
   regcache_cpy (current_regcache, dummy_frame->regcache);
   flush_cached_frames ();
 
-  regcache_xfree (dummy_frame->regcache);
-  xfree (dummy_frame);
+  discard_innermost_dummy (&dummy_frame_stack);
 }
 
 /* Function: fix_call_dummy
@@ -304,7 +343,7 @@ generic_fix_call_dummy (char *dummy, CORE_ADDR pc, CORE_ADDR fun, int nargs,
 /* Given a call-dummy dummy-frame, return the registers.  Here the
    register value is taken from the local copy of the register buffer.  */
 
-void
+static void
 dummy_frame_register_unwind (struct frame_info *frame, void **cache,
                             int regnum, int *optimized,
                             enum lval_type *lvalp, CORE_ADDR *addrp,
@@ -331,7 +370,10 @@ dummy_frame_register_unwind (struct frame_info *frame, void **cache,
     }
 }
 
-CORE_ADDR
+/* Assuming that FRAME is a dummy, return the resume address for the
+   previous frame.  */
+
+static CORE_ADDR
 dummy_frame_pc_unwind (struct frame_info *frame,
                       void **cache)
 {
@@ -345,8 +387,12 @@ dummy_frame_pc_unwind (struct frame_info *frame,
 }
 
 
-void
-dummy_frame_id_unwind (struct frame_info *frame, void **cache,
+/* Assuming that FRAME is a dummy, return the ID of the calling frame
+   (the frame that the dummy has the saved state of).  */
+
+static void
+dummy_frame_id_unwind (struct frame_info *frame,
+                      void **cache,
                       struct frame_id *id)
 {
   struct dummy_frame *dummy = cached_find_dummy_frame (frame, cache);
@@ -359,3 +405,21 @@ dummy_frame_id_unwind (struct frame_info *frame, void **cache,
     (*id) = dummy->id;
 }
 
+static struct frame_unwind dummy_frame_unwind =
+{
+  dummy_frame_pop,
+  dummy_frame_pc_unwind,
+  dummy_frame_id_unwind,
+  dummy_frame_register_unwind
+};
+
+const struct frame_unwind *
+dummy_frame_p (CORE_ADDR pc)
+{
+  if (DEPRECATED_PC_IN_CALL_DUMMY_P ()
+      ? DEPRECATED_PC_IN_CALL_DUMMY (pc, 0, 0)
+      : pc_in_dummy_frame (pc))
+    return &dummy_frame_unwind;
+  else
+    return NULL;
+}
This page took 0.023664 seconds and 4 git commands to generate.