2003-03-12 Andrew Cagney <cagney@redhat.com>
authorAndrew Cagney <cagney@redhat.com>
Wed, 12 Mar 2003 15:39:30 +0000 (15:39 +0000)
committerAndrew Cagney <cagney@redhat.com>
Wed, 12 Mar 2003 15:39:30 +0000 (15:39 +0000)
Eliminate the need for POP_FRAME.
* frame.c (do_frame_unwind_register): New function.
(frame_pop): When no POP_FRAME, pop the frame using register
unwind and a scratch regcache.
(frame_saved_regs_pop): Delete function.
(trad_frame_unwinder): Update.
* d10v-tdep.c (d10v_frame_pop): Delete function.
(d10v_frame_unwind): Update.
* sentinel-frame.c (sentinel_frame_pop): Delete function.
(sentinel_frame_unwinder): Update.
* dummy-frame.c (dummy_frame_pop): Delete function.
(dummy_frame_unwind): Update.
* frame-unwind.h (frame_unwind_pop_ftype): Delete definition.
(struct frame_unwind): Update.

gdb/ChangeLog
gdb/d10v-tdep.c
gdb/dummy-frame.c
gdb/frame-unwind.h
gdb/frame.c
gdb/sentinel-frame.c

index 037fc7476accecc3d6623a437b7f8870f142968a..889570abfd663157d3f4bd95f498c804fbcd32e5 100644 (file)
@@ -1,3 +1,20 @@
+2003-03-12  Andrew Cagney  <cagney@redhat.com>
+
+       Eliminate the need for POP_FRAME.
+       * frame.c (do_frame_unwind_register): New function.
+       (frame_pop): When no POP_FRAME, pop the frame using register
+       unwind and a scratch regcache.
+       (frame_saved_regs_pop): Delete function.
+       (trad_frame_unwinder): Update.
+       * d10v-tdep.c (d10v_frame_pop): Delete function.
+       (d10v_frame_unwind): Update.
+       * sentinel-frame.c (sentinel_frame_pop): Delete function.
+       (sentinel_frame_unwinder): Update.
+       * dummy-frame.c (dummy_frame_pop): Delete function.
+       (dummy_frame_unwind): Update.
+       * frame-unwind.h (frame_unwind_pop_ftype): Delete definition.
+       (struct frame_unwind): Update.
+
 2003-03-11  Kevin Buettner  <kevinb@redhat.com>
 
        * mips-tdep.c (mips_ecoff_reg_to_regnum): Rename to
index 516cde468ad625270aeabe7c5b2bf8c47a63b3d5..b60ce7fad3a2ea5f96bb506e38f5718c5d0ab79f 100644 (file)
@@ -1572,45 +1572,7 @@ d10v_frame_register_unwind (struct frame_info *frame,
 }
 
 
-static void
-d10v_frame_pop (struct frame_info *fi, void **unwind_cache,
-               struct regcache *regcache)
-{
-  struct d10v_unwind_cache *info = d10v_frame_unwind_cache (fi, unwind_cache);
-  CORE_ADDR fp;
-  int regnum;
-  char raw_buffer[8];
-
-  fp = get_frame_base (fi);
-
-  /* now update the current registers with the old values */
-  for (regnum = A0_REGNUM; regnum < A0_REGNUM + NR_A_REGS; regnum++)
-    {
-      frame_unwind_register (fi, regnum, raw_buffer);
-      regcache_cooked_write (regcache, regnum, raw_buffer);
-    }
-  for (regnum = 0; regnum < SP_REGNUM; regnum++)
-    {
-      frame_unwind_register (fi, regnum, raw_buffer);
-      regcache_cooked_write (regcache, regnum, raw_buffer);
-    }
-  frame_unwind_register (fi, PSW_REGNUM, raw_buffer);
-  regcache_cooked_write (regcache, PSW_REGNUM, raw_buffer);
-
-  frame_unwind_register (fi, PC_REGNUM, raw_buffer);
-  regcache_cooked_write (regcache, PC_REGNUM, raw_buffer);
-
-  store_unsigned_integer (raw_buffer,
-                         register_size (current_gdbarch, SP_REGNUM),
-                         fp + info->size);
-  regcache_cooked_write (regcache, SP_REGNUM, raw_buffer);
-
-  target_store_registers (-1);
-  flush_cached_frames ();
-}
-
 static struct frame_unwind d10v_frame_unwind = {
-  d10v_frame_pop,
   d10v_frame_id_unwind,
   d10v_frame_register_unwind
 };
index 95c859889a8e9e0a1c8a4bb03738ae10c16e89fd..bf4a31c1ef426e3abcefd810e50622fcd0fb8f4f 100644 (file)
@@ -282,37 +282,6 @@ discard_innermost_dummy (struct dummy_frame **stack)
   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)
 {
@@ -390,7 +359,6 @@ dummy_frame_id_unwind (struct frame_info *frame,
 
 static struct frame_unwind dummy_frame_unwind =
 {
-  dummy_frame_pop,
   dummy_frame_id_unwind,
   dummy_frame_register_unwind
 };
index 7f4a866b1ebb00a8ae6c9639ab7311b058a5064c..5d85efe9c09dd33a96ebd5cbd314dd915d7ac64b 100644 (file)
@@ -76,27 +76,11 @@ typedef void (frame_unwind_id_ftype) (struct frame_info * frame,
                                      void **unwind_cache,
                                      struct frame_id * id);
 
-/* Discard the frame by restoring the registers (in regcache) back to
-   that of the caller.  */
-/* NOTE: cagney/2003-01-19: While at present the callers all pop each
-   frame in turn, the implementor should try to code things so that
-   any frame can be popped directly.  */
-/* FIXME: cagney/2003-01-19: Since both FRAME and REGCACHE refer to a
-   common register cache, care must be taken when restoring the
-   registers.  The `correct fix' is to first first save the registers
-   in a scratch cache, and second write that scratch cache back to to
-   the real register cache.  */
-
-typedef void (frame_unwind_pop_ftype) (struct frame_info *frame,
-                                      void **unwind_cache,
-                                      struct regcache *regcache);
-
 struct frame_unwind
 {
   /* Should the frame's type go here? */
   /* Should an attribute indicating the frame's address-in-block go
      here?  */
-  frame_unwind_pop_ftype *pop;
   frame_unwind_id_ftype *id;
   frame_unwind_reg_ftype *reg;
 };
index 0bef68b2a1192eecc5c1d9da09a59040b9d2700a..7af6ad1a713d6c0d13d1efff65a8e854dda16406 100644 (file)
@@ -185,16 +185,44 @@ frame_pc_unwind (struct frame_info *this_frame)
   return this_frame->pc_unwind_cache;
 }
 
+static int
+do_frame_unwind_register (void *src, int regnum, void *buf)
+{
+  frame_unwind_register (src, regnum, buf);
+  return 1;
+}
+
 void
-frame_pop (struct frame_info *frame)
+frame_pop (struct frame_info *this_frame)
 {
-  /* FIXME: cagney/2003-01-18: There is probably a chicken-egg problem
-     with passing in current_regcache.  The pop function needs to be
-     written carefully so as to not overwrite registers whose [old]
-     values are needed to restore other registers.  Instead, this code
-     should pass in a scratch cache and, as a second step, restore the
-     registers using that.  */
-  frame->unwind->pop (frame, &frame->unwind_cache, current_regcache);
+  struct regcache *scratch_regcache;
+  struct cleanup *cleanups;
+
+  if (POP_FRAME_P ())
+    {
+      /* A legacy architecture that has implemented a custom pop
+        function.  All new architectures should instead be using the
+        generic code below.  */
+      POP_FRAME;
+    }
+  else
+    {
+      /* Make a copy of all the register values unwound from this
+        frame.  Save them in a scratch buffer so that there isn't a
+        race betweening trying to extract the old values from the
+        current_regcache while, at the same time writing new values
+        into that same cache.  */
+      struct regcache *scratch = regcache_xmalloc (current_gdbarch);
+      struct cleanup *cleanups = make_cleanup_regcache_xfree (scratch);
+      regcache_save (scratch, do_frame_unwind_register, this_frame);
+      /* Now copy those saved registers into the current regcache.
+         Here, regcache_cpy() calls regcache_restore().  */
+      regcache_cpy (current_regcache, scratch);
+      do_cleanups (cleanups);
+    }
+  /* We've made right mess of GDB's local state, just discard
+     everything.  */
+  target_store_registers (-1);
   flush_cached_frames ();
 }
 
@@ -768,16 +796,7 @@ frame_saved_regs_id_unwind (struct frame_info *next_frame, void **cache,
   id->base = base;
 }
        
-static void
-frame_saved_regs_pop (struct frame_info *fi, void **cache,
-                     struct regcache *regcache)
-{
-  gdb_assert (POP_FRAME_P ());
-  POP_FRAME;
-}
-
 const struct frame_unwind trad_frame_unwinder = {
-  frame_saved_regs_pop,
   frame_saved_regs_id_unwind,
   frame_saved_regs_register_unwind
 };
index 2b1616a1f8cacb4fc6758e16cc10aa7751d14c5b..961e0300ea61725da9f7a3b5932f01cd9803131a 100644 (file)
@@ -83,17 +83,8 @@ sentinel_frame_id_unwind (struct frame_info *frame,
   id->pc = read_pc ();
 }
 
-static void
-sentinel_frame_pop (struct frame_info *frame,
-                   void **cache,
-                   struct regcache *regcache)
-{
-  internal_error (__FILE__, __LINE__, "Function sentinal_frame_pop called");
-}
-
 const struct frame_unwind sentinel_frame_unwinder =
 {
-  sentinel_frame_pop,
   sentinel_frame_id_unwind,
   sentinel_frame_register_unwind
 };