]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
2003-03-06 Andrew Cagney <cagney@redhat.com>
authorAndrew Cagney <cagney@redhat.com>
Fri, 7 Mar 2003 14:24:29 +0000 (14:24 +0000)
committerAndrew Cagney <cagney@redhat.com>
Fri, 7 Mar 2003 14:24:29 +0000 (14:24 +0000)
* d10v-tdep.c (d10v_frame_pop): Delete function.
(d10v_frame_unwind): Update.
* frame.c: Include "reggroups.h".
* regcache.c (regcache_raw_write): Allow writes to a readonly
regcache.
* frame.c (frame_saved_regs_pop): Delete function.
(trad_frame_unwinder): Update
(frame_pop): Rewrite.
* 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/regcache.c
gdb/sentinel-frame.c

index b2510c3a36d37e26a2bd45d257634077feb959ee..8b9d6f67b5cd96d9f714e841b7693e24958c6c72 100644 (file)
@@ -1,3 +1,29 @@
+2003-03-06  Andrew Cagney  <cagney@redhat.com>
+
+       * d10v-tdep.c (d10v_frame_pop): Delete function.
+       (d10v_frame_unwind): Update.
+
+       * frame.c: Include "reggroups.h".
+
+       * regcache.c (regcache_raw_write): Allow writes to a readonly
+       regcache.
+
+       * frame.c (frame_saved_regs_pop): Delete function.
+       (trad_frame_unwinder): Update
+       (frame_pop): Rewrite.
+
+       * 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.
+       * gdbarch.sh (POP): New method
+       * gdbarch.h, gdbarch.c: Re-generate.
+
+
 2003-03-06  Andrew Cagney  <cagney@redhat.com>
 
        * gdbarch.sh (gdbarch_unwind_pc): New method.
index 0fe222ec2fe26a431f1ef7bacfb8ebd4ce158ec4..1848bf1003530c75629d4cf1f21e0636be55e167 100644 (file)
@@ -1578,42 +1578,7 @@ d10v_frame_register_unwind (struct frame_info *next_frame,
                         lvalp, addrp, realnump, bufferp);
 }
 
-static void
-d10v_frame_pop (struct frame_info *next_frame, void **this_cache,
-               struct regcache *regcache)
-{
-  struct d10v_unwind_cache *info
-    = d10v_frame_unwind_cache (next_frame, this_cache);
-  CORE_ADDR fp;
-  int regnum;
-  char raw_buffer[8];
-
-  /* now update the current registers with the old values */
-  for (regnum = A0_REGNUM; regnum < A0_REGNUM + NR_A_REGS; regnum++)
-    {
-      saved_regs_unwind (next_frame, info->saved_regs, regnum, raw_buffer);
-      regcache_cooked_write (regcache, regnum, raw_buffer);
-    }
-  for (regnum = 0; regnum < SP_REGNUM; regnum++)
-    {
-      saved_regs_unwind (next_frame, info->saved_regs, regnum, raw_buffer);
-      regcache_cooked_write (regcache, regnum, raw_buffer);
-    }
-  saved_regs_unwind (next_frame, info->saved_regs, PSW_REGNUM, raw_buffer);
-  regcache_cooked_write (regcache, PSW_REGNUM, raw_buffer);
-
-  saved_regs_unwind (next_frame, info->saved_regs, LR_REGNUM, raw_buffer);
-  regcache_cooked_write (regcache, PC_REGNUM, raw_buffer);
-
-  saved_regs_unwind (next_frame, info->saved_regs, SP_REGNUM, raw_buffer);
-  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 a44f4510dbccd1f6e8544405ade90e1194384b38..c00e3c139c8e60d3dc3deb763890935d17f73656 100644 (file)
@@ -288,37 +288,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 *next_frame, void **this_cache,
-                struct regcache *regcache)
-{
-  struct dummy_frame *dummy = cached_find_dummy_frame (next_frame, this_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)
 {
@@ -405,7 +374,6 @@ dummy_frame_id_unwind (struct frame_info *next_frame,
 
 static struct frame_unwind dummy_frame_unwind =
 {
-  dummy_frame_pop,
   dummy_frame_id_unwind,
   dummy_frame_register_unwind
 };
index 4d00b2f5e19f8f6fb4cda99e0a42934836ea50b2..3efe1e26f471b3faaaf468193dee71483361f2ef 100644 (file)
@@ -102,35 +102,11 @@ typedef void (frame_unwind_reg_ftype) (struct frame_info *next_frame,
                                       CORE_ADDR *addrp,
                                       int *realnump, void *valuep);
 
-/* Assuming the frame chain: (outer) prev <-> this <-> next (inner);
-   use the NEXT frame, and its register unwind method, to unwind THIS
-   frame's entire stack, writing PREV's frames register values into
-   REGCACHE.
-
-   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.
-
-   FIXME: cagney/2003-03-04: Isn't this entire function redundant?
-   Shouldn't the code instead just iterate through the restore
-   reggroup unwinding those registers?  */
-
-typedef void (frame_unwind_pop_ftype) (struct frame_info *next_frame,
-                                      void **this_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 d61ec08ee8c0b1f95dc91b9b695c530a15d79a99..1a1c050a01a2266818c68b5f7d3a2dbf18004ed9 100644 (file)
@@ -38,6 +38,7 @@
 #include "frame-unwind.h"
 #include "command.h"
 #include "gdbcmd.h"
+#include "reggroups.h"
 
 /* Flag to control debugging.  */
 
@@ -135,9 +136,9 @@ frame_find_by_id (struct frame_id id)
 }
 
 CORE_ADDR
-frame_pc_unwind (struct frame_info *next_frame)
+frame_pc_unwind (struct frame_info *this_frame)
 {
-  if (!next_frame->pc_unwind_cache_p)
+  if (!this_frame->pc_unwind_cache_p)
     {
       CORE_ADDR pc;
       if (gdbarch_unwind_pc_p (current_gdbarch))
@@ -148,7 +149,7 @@ frame_pc_unwind (struct frame_info *next_frame)
             the value of this frame's PC (resume address).  A typical
             implementation is no more than:
           
-            frame_unwind_register (next_frame, ISA_PC_REGNUM, buf);
+            frame_unwind_register (this_frame, ISA_PC_REGNUM, buf);
             return extract_address (buf, size of ISA_PC_REGNUM);
 
             Note: this method is very heavily dependent on a correct
@@ -158,9 +159,9 @@ frame_pc_unwind (struct frame_info *next_frame)
             frame.  This is all in stark contrast to the old
             FRAME_SAVED_PC which would try to directly handle all the
             different ways that a PC could be unwound.  */
-         pc = gdbarch_unwind_pc (current_gdbarch, next_frame);
+         pc = gdbarch_unwind_pc (current_gdbarch, this_frame);
        }
-      else if (next_frame->level < 0)
+      else if (this_frame->level < 0)
        {
          /* FIXME: cagney/2003-03-06: Old code and and a sentinel
              frame.  Do like was always done.  Fetch the PC's value
@@ -175,26 +176,52 @@ frame_pc_unwind (struct frame_info *next_frame)
              frame.  Do like was always done.  Note that this method,
              unlike unwind_pc(), tries to handle all the different
              frame cases directly.  It fails.  */
-         pc = FRAME_SAVED_PC (next_frame);
+         pc = FRAME_SAVED_PC (this_frame);
        }
       else
        internal_error (__FILE__, __LINE__, "No gdbarch_unwind_pc method");
-      next_frame->pc_unwind_cache = pc;
-      next_frame->pc_unwind_cache_p = 1;
+      this_frame->pc_unwind_cache = pc;
+      this_frame->pc_unwind_cache_p = 1;
     }
-  return next_frame->pc_unwind_cache;
+  return this_frame->pc_unwind_cache;
 }
 
 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->next, &frame->unwind_cache, current_regcache);
+  if (POP_FRAME_P ())
+    {
+      POP_FRAME;
+    }
+  else
+    {
+      /* Note, the dummy-frame code does something very similar to
+         this.  Perhaphs a common routine is in order.  */
+      struct regcache *scratch_regcache = regcache_xmalloc (current_gdbarch);
+      struct cleanup *cleanups = make_cleanup_regcache_xfree (scratch_regcache);
+      void *buf = alloca (max_register_size (current_gdbarch));
+      int regnum;
+
+      /* Copy over any registers (identified by their membership in
+        the save_reggroup) and mark them as valid.  The full [0
+        .. NUM_REGS+NUM_PSEUDO_REGS) range is checked since some
+        architectures need to save/restore `cooked' registers that
+        live in memory.  */
+      for (regnum = 0; regnum < NUM_REGS + NUM_PSEUDO_REGS; regnum++)
+       {
+         if (gdbarch_register_reggroup_p (current_gdbarch, regnum,
+                                          save_reggroup))
+           {
+             frame_unwind_register (this_frame, regnum, buf);
+             regcache_cooked_write (scratch_regcache, regnum, buf);
+           }
+       }
+
+      /* Now write the unwound registers, en-mass, back into the
+         regcache.  */
+      regcache_cpy (current_regcache, scratch_regcache);
+      do_cleanups (cleanups);
+    }
   flush_cached_frames ();
 }
 
@@ -770,16 +797,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 3f2be7bc060076cc2ad705e72dc854e36a46261c..1b862e187eb1f89666c7c23e7d1987d3a9f452f1 100644 (file)
@@ -929,7 +929,14 @@ regcache_raw_write (struct regcache *regcache, int regnum, const void *buf)
 {
   gdb_assert (regcache != NULL && buf != NULL);
   gdb_assert (regnum >= 0 && regnum < regcache->descr->nr_raw_registers);
-  gdb_assert (!regcache->readonly_p);
+
+  if (regcache->readonly_p)
+    {
+      memcpy (register_buffer (regcache, regnum), buf,
+             regcache->descr->sizeof_register[regnum]);
+      regcache->register_valid_p[regnum] = 1;
+      return;
+    }
 
   if (regcache->descr->legacy_p)
     {
index 046655f068748f42779ddc51a977c9c0f4879e70..8d92bfc01ca9ad66cb59b49a3934495262524d63 100644 (file)
@@ -84,17 +84,8 @@ sentinel_frame_id_unwind (struct frame_info *next_frame,
   internal_error (__FILE__, __LINE__, "sentinel_frame_id_unwind called");
 }
 
-static void
-sentinel_frame_pop (struct frame_info *next_frame,
-                   void **this_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
 };