2003-03-10 Andrew Cagney <cagney@redhat.com>
authorAndrew Cagney <cagney@redhat.com>
Mon, 10 Mar 2003 19:08:47 +0000 (19:08 +0000)
committerAndrew Cagney <cagney@redhat.com>
Mon, 10 Mar 2003 19:08:47 +0000 (19:08 +0000)
* regcache.h (regcache_cooked_read_ftype): Define.
(regcache_save, regcache_restore): Add a cooked_read parameter.
* regcache.c (regcache_save, regcache_restore): Update.
(do_cooked_read): New function.
(regcache_cpy): Pass do_cooked_read to regcache_save and
regcache_restore.

gdb/ChangeLog
gdb/regcache.c
gdb/regcache.h

index 4a4a5f43e55c82f545151581795e5794f0f1f018..d13b7e722f94764c6e58167191653a7b7148e104 100644 (file)
@@ -1,3 +1,12 @@
+2003-03-10  Andrew Cagney  <cagney@redhat.com>
+
+       * regcache.h (regcache_cooked_read_ftype): Define.
+       (regcache_save, regcache_restore): Add a cooked_read parameter.
+       * regcache.c (regcache_save, regcache_restore): Update.
+       (do_cooked_read): New function.
+       (regcache_cpy): Pass do_cooked_read to regcache_save and
+       regcache_restore.
+
 2003-03-10  Andrew Cagney  <cagney@redhat.com>
 
        * gdbarch.sh (gdbarch_unwind_pc): New method.
index 3f2be7bc060076cc2ad705e72dc854e36a46261c..5475cf681ef24a6a724c68ecbc94b5c8129b2bba 100644 (file)
@@ -389,59 +389,79 @@ register_buffer (struct regcache *regcache, int regnum)
 }
 
 void
-regcache_save (struct regcache *dst, struct regcache *src)
+regcache_save (struct regcache *dst, regcache_cooked_read_ftype *cooked_read,
+              void *src)
 {
   struct gdbarch *gdbarch = dst->descr->gdbarch;
+  void *buf = alloca (max_register_size (gdbarch));
   int regnum;
-  /* The SRC and DST register caches had better belong to the same
-     architecture.  */
-  gdb_assert (src->descr->gdbarch == dst->descr->gdbarch);
   /* The DST should be `read-only', if it wasn't then the save would
-     end up trying to write the register values out through to the
+     end up trying to write the register values back out to the
      target.  */
-  gdb_assert (!src->readonly_p);
   gdb_assert (dst->readonly_p);
   /* Clear the dest.  */
   memset (dst->registers, 0, dst->descr->sizeof_cooked_registers);
   memset (dst->register_valid_p, 0, dst->descr->sizeof_cooked_register_valid_p);
   /* 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.  */
+     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 < dst->descr->nr_cooked_registers; regnum++)
     {
       if (gdbarch_register_reggroup_p (gdbarch, regnum, save_reggroup))
        {
-         regcache_cooked_read (src, regnum, register_buffer (dst, regnum));
-         dst->register_valid_p[regnum] = 1;
+         int valid = cooked_read (src, regnum, buf);
+         if (valid)
+           {
+             memcpy (register_buffer (dst, regnum), buf,
+                     register_size (gdbarch, regnum));
+             dst->register_valid_p[regnum] = 1;
+           }
        }
     }
 }
 
 void
-regcache_restore (struct regcache *dst, struct regcache *src)
+regcache_restore (struct regcache *dst,
+                 regcache_cooked_read_ftype *cooked_read,
+                 void *src)
 {
   struct gdbarch *gdbarch = dst->descr->gdbarch;
+  void *buf = alloca (max_register_size (gdbarch));
   int regnum;
-  gdb_assert (src->descr->gdbarch == dst->descr->gdbarch);
+  /* The dst had better not be read-only.  If it is, the `restore'
+     doesn't make much sense.  */
   gdb_assert (!dst->readonly_p);
-  gdb_assert (src->readonly_p);
   /* Copy over any registers, being careful to only restore those that
-     were both saved and need to be restored.  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 < src->descr->nr_cooked_registers; regnum++)
+     were both saved and need to be restored.  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 < dst->descr->nr_cooked_registers; regnum++)
     {
-      if (gdbarch_register_reggroup_p (gdbarch, regnum, restore_reggroup)
-         && src->register_valid_p[regnum])
+      if (gdbarch_register_reggroup_p (gdbarch, regnum, restore_reggroup))
        {
-         regcache_cooked_write (dst, regnum, register_buffer (src, regnum));
+         int valid = cooked_read (src, regnum, buf);
+         if (valid)
+           regcache_cooked_write (dst, regnum, buf);
        }
     }
 }
 
+static int
+do_cooked_read (void *src, int regnum, void *buf)
+{
+  struct regcache *regcache = src;
+  if (!regcache_valid_p (regcache, regnum)
+      && regcache->readonly_p)
+    /* Don't even think about fetching a register from a read-only
+       cache when the register isn't yet valid.  There isn't a target
+       from which the register value can be fetched.  */
+    return 0;
+  regcache_cooked_read (regcache, regnum, buf);
+  return 1;
+}
+
+
 void
 regcache_cpy (struct regcache *dst, struct regcache *src)
 {
@@ -452,9 +472,9 @@ regcache_cpy (struct regcache *dst, struct regcache *src)
   gdb_assert (src != dst);
   gdb_assert (src->readonly_p || dst->readonly_p);
   if (!src->readonly_p)
-    regcache_save (dst, src);
+    regcache_save (dst, do_cooked_read, src);
   else if (!dst->readonly_p)
-    regcache_restore (dst, src);
+    regcache_restore (dst, do_cooked_read, src);
   else
     regcache_cpy_no_passthrough (dst, src);
 }
index ee1050536056de08f98bd908332c3aa7a3311f6d..dd629383bebe1b00dad3662ab7d6ef21fe028a06 100644 (file)
@@ -155,15 +155,19 @@ extern int max_register_size (struct gdbarch *gdbarch);
 extern int register_size (struct gdbarch *gdbarch, int regnum);
 
 
-/* Save/restore a register cache.  The registers saved/restored is
-   determined by the save_reggroup and restore_reggroup (although you
-   can't restore a register that wasn't saved as well :-).  You can
-   only save to a read-only cache (default from regcache_xmalloc())
-   from a live cache and you can only restore from a read-only cache
-   to a live cache.  */
-
-extern void regcache_save (struct regcache *dst, struct regcache *src);
-extern void regcache_restore (struct regcache *dst, struct regcache *src);
+/* Save/restore a register cache.  The set of registers saved /
+   restored into the DST regcache determined by the save_reggroup /
+   restore_reggroup respectively.  COOKED_READ returns zero iff the
+   register's value can't be returned.  */
+
+typedef int (regcache_cooked_read_ftype) (void *src, int regnum, void *buf);
+
+extern void regcache_save (struct regcache *dst,
+                          regcache_cooked_read_ftype *cooked_read,
+                          void *src);
+extern void regcache_restore (struct regcache *dst,
+                             regcache_cooked_read_ftype *cooked_read,
+                             void *src);
 
 /* Copy/duplicate the contents of a register cache.  By default, the
    operation is pass-through.  Writes to DST and reads from SRC will