]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
introduce regcache_move.
authorAndrew Cagney <cagney@redhat.com>
Fri, 17 May 2002 15:06:31 +0000 (15:06 +0000)
committerAndrew Cagney <cagney@redhat.com>
Fri, 17 May 2002 15:06:31 +0000 (15:06 +0000)
Fix cases where normal vs no_passthroug copies didn't reflect the old code.

gdb/ChangeLog
gdb/blockframe.c
gdb/infcmd.c
gdb/infrun.c
gdb/regcache.c
gdb/regcache.h

index 11bcf3d77f75a077f9bbc951d16c09e0ffd16be7..742d060137a04dcc735cbf5c08a2e3152654fe5a 100644 (file)
@@ -1,5 +1,31 @@
-2002-05-16  Andrew Cagney  <ac131313@redhat.com>
-
+2002-05-17  Andrew Cagney  <ac131313@redhat.com>
+
+*** FIXME: the regcache_desc should contain max_register_size.
+
+       * regcache.c (regcache_move): New function.
+       (regcache_save): Rewrite, handle pre and post
+       gdbarch_register_read_p with regcache_move.
+       (regcache_dup): Ditto
+       (regcache_dup_no_passthrough): Ditto ditto.
+       (regcache_save_no_passthrough): Ditto ditto.
+       (regcache_restore): Ditto ditto.
+       (regcache_restore_no_passthrough): Ditto ditto.
+       * regcache.h: Upate
+
+       * infrun.c (save_inferior_status): Use regcache_dup_no_passthrough
+       instead of regcache_dup.  Use regcache dup instead of
+       regcache_xmalloc, regcache_save.  Revert white space change.
+
+       * infcmd.c (run_stack_dummy): Use regcache_dup_no_passthrough not
+       regcache_dup.
+
+       * blockframe.c (generic_push_dummy_frame): Re-order regcache_save
+       call to so that the patch is better.
+
+       * regcache.c (regcache_save_no_passthrough): New function.
+       (regcache_dup_no_passthrough): Ditto.
+       (regcache_restore_no_passthrough): Rename to
+       regcache_restore_no_writethrough.
 
        * blockframe.c, regbuf.c, rs6000-tdep.c: Include "regcache.h".
 
index 477a8a3e2f52e8bf2ce56678f7cf6b0715f9ab2f..78b31eff4386a3ce9cee37bee469fb54ac47c977 100644 (file)
@@ -1170,12 +1170,12 @@ generic_push_dummy_frame (void)
 
   dummy_frame = xmalloc (sizeof (struct dummy_frame));
   dummy_frame->regcache = regcache_xmalloc (current_gdbarch);
-  regcache_save (dummy_frame->regcache);
 
   dummy_frame->pc = read_pc ();
   dummy_frame->sp = read_sp ();
   dummy_frame->top = dummy_frame->sp;
   dummy_frame->fp = fp;
+  regcache_save (dummy_frame->regcache);
   dummy_frame->next = dummy_frame_stack;
   dummy_frame_stack = dummy_frame;
 }
index 14bb00bda49cd5a05974d08a2f3f17125995c1f0..ae5d52539024072ace01ef95a148bc90b3c86e13 100644 (file)
@@ -1043,7 +1043,7 @@ run_stack_dummy (CORE_ADDR addr, struct regcache **buffer)
     return 2;
 
   /* On normal return, the stack dummy has been popped already.  */
-  *buffer = regcache_dup (stop_registers);
+  *buffer = regcache_dup_no_passthrough (stop_registers);
   return 0;
 }
 \f
index b46779160edadff769a0291fc2105e6654bba54a..409fede4d1d87317bf5f61d3ed0046c7800742e4 100644 (file)
@@ -3961,9 +3961,9 @@ save_inferior_status (int restore_stack_info)
   inf_status->restore_stack_info = restore_stack_info;
   inf_status->proceed_to_finish = proceed_to_finish;
 
-  inf_status->stop_registers = regcache_dup (stop_registers);
-  inf_status->registers = regcache_xmalloc (current_gdbarch);
-  regcache_save (inf_status->registers);
+  inf_status->stop_registers = regcache_dup_no_passthrough (stop_registers);
+
+  inf_status->registers = regcache_dup (current_regcache);
 
   record_selected_frame (&(inf_status->selected_frame_address),
                         &(inf_status->selected_level));
@@ -4027,7 +4027,7 @@ restore_inferior_status (struct inferior_status *inf_status)
   breakpoint_proceeded = inf_status->breakpoint_proceeded;
   proceed_to_finish = inf_status->proceed_to_finish;
 
-  /* FIXME: Is the restore of stop_registers always needed */
+  /* FIXME: Is the restore of stop_registers always needed. */
   regcache_xfree (stop_registers);
   stop_registers = inf_status->stop_registers;
 
index 38f611c63c2f250528711a9718c4c39cc2317f3e..3c9617658e025e5deef8786c446ae53438aa932a 100644 (file)
@@ -182,16 +182,65 @@ regcache_xmalloc_with_cleanup (struct gdbarch *gdbarch)
   return regcache;
 }
 
+void
+regcache_move (struct regcache *dst, struct regcache *src)
+{
+  int i;
+  char *buf = alloca (MAX_REGISTER_RAW_SIZE);
+  gdb_assert (src != NULL && dst != NULL);
+  gdb_assert (src->descr->gdbarch == dst->descr->gdbarch);
+  /* FIXME: cagney/2002-05-17: To say this bit is bad is being polite.
+     It keeps the existing code working where things rely on going
+     through the register cache.  */
+  if (src == current_regcache
+      && !gdbarch_register_read_p (src->descr->gdbarch))
+    {
+      /* ULGH!!!!  Old way.  Use REGISTER bytes and let code below
+        untangle fetch.  */
+      read_register_bytes (0, dst->registers, REGISTER_BYTES);
+      return;
+    }
+  for (i = 0; i < current_regcache->descr->nr_registers; i++)
+    {
+      /* Should we worry about the valid bit here?  */
+      regcache_read (src, i, buf);
+      regcache_write (dst, i, buf);
+    }
+}
+
+void
+regcache_move_no_passthrough (struct regcache *dst, struct regcache *src)
+{
+  int i;
+  gdb_assert (src != NULL && dst != NULL);
+  gdb_assert (src->descr->gdbarch == dst->descr->gdbarch);
+  /* NOTE: cagney/2002-05-17: Don't let the caller do a no-passthrough
+     move of data into the current_regcache().  Doing this would be
+     silly - it would mean that valid_p would be completly invalid.  */
+  gdb_assert (dst != current_regcache);
+  memcpy (dst->registers, src->registers,
+         dst->descr->sizeof_registers);
+  memcpy (dst->register_valid_p, src->register_valid_p,
+         dst->descr->sizeof_register_valid_p);
+}
+
 struct regcache *
-regcache_dup (struct regcache *regcache)
+regcache_dup (struct regcache *src)
 {
   struct regcache *newbuf;
   gdb_assert (current_regcache != NULL);
-  newbuf = regcache_xmalloc (regcache->descr->gdbarch);
-  memcpy (newbuf->registers, regcache->registers,
-         regcache->descr->sizeof_registers);
-  memcpy (newbuf->register_valid_p, regcache->register_valid_p,
-         regcache->descr->sizeof_register_valid_p);
+  newbuf = regcache_xmalloc (src->descr->gdbarch);
+  regcache_move (newbuf, src);
+  return newbuf;
+}
+
+struct regcache *
+regcache_dup_no_passthrough (struct regcache *src)
+{
+  struct regcache *newbuf;
+  gdb_assert (current_regcache != NULL);
+  newbuf = regcache_xmalloc (src->descr->gdbarch);
+  regcache_move_no_passthrough (newbuf, src);
   return newbuf;
 }
 
@@ -982,36 +1031,38 @@ build_regcache (void)
 void
 regcache_save (struct regcache *regcache)
 {
+  int i;
+  char *buf = alloca (MAX_REGISTER_RAW_SIZE);
   gdb_assert (current_regcache != NULL && regcache != NULL);
   gdb_assert (current_regcache->descr->gdbarch == regcache->descr->gdbarch);
-  memcpy (grub_around_regcache_for_registers (regcache),
-         grub_around_regcache_for_registers (current_regcache),
-         regcache->descr->sizeof_registers);
-  memcpy (grub_around_regcache_for_register_valid (regcache),
-         grub_around_regcache_for_register_valid (current_regcache),
-         regcache->descr->sizeof_register_valid_p);
+  regcache_move (regcache, current_regcache);
+}
+
+void
+regcache_save_no_passthrough (struct regcache *regcache)
+{
+  gdb_assert (current_regcache != NULL && regcache != NULL);
+  gdb_assert (current_regcache->descr->gdbarch == regcache->descr->gdbarch);
+  regcache_move_no_passthrough (regcache, current_regcache);
 }
 
 void
 regcache_restore (struct regcache *regcache)
 {
-  char *regcache_registers;
+  int i;
+  char *buf = alloca (MAX_REGISTER_RAW_SIZE);
   gdb_assert (current_regcache != NULL && regcache != NULL);
   gdb_assert (current_regcache->descr->gdbarch == regcache->descr->gdbarch);
-  regcache_registers = grub_around_regcache_for_registers (regcache);
-  /* NOTE: cagney, this should be regcache->sizeof_registers but,
-     again, things are screwed as it might copy pseudo registers.  */
-  write_register_bytes (0, regcache_registers, REGISTER_BYTES);
+  regcache_move (current_regcache, regcache);
 }
 
 void
-regcache_restore_no_writethrough (struct regcache *regcache)
+regcache_restore_no_passthrough (struct regcache *regcache)
 {
   char *regcache_registers;
   gdb_assert (current_regcache != NULL && regcache != NULL);
   gdb_assert (current_regcache->descr->gdbarch == regcache->descr->gdbarch);
-  regcache_registers = grub_around_regcache_for_registers (regcache);
-  memcpy (registers, regcache_registers, REGISTER_BYTES);
+  regcache_move_no_passthrough (current_regcache, regcache);
 }
 
 void
index 8a209d80553e5bec637544316ef9ac916d6cb6cd..931393527fc7c742a46cdc2324658edb20c96c6e 100644 (file)
@@ -59,12 +59,19 @@ extern signed char *register_valid;
 
 /* Save/restore the register cache using the regbuf.  The operation is
    write through - it is strictly for code that needs to restore the
-   target's registers to a previous state.  */
+   target's registers to a previous state.
+
+   ``no passthrough'' versions do not go through to the target.  They
+   only save values already in the cache.  */
 
 extern void regcache_save (struct regcache *regcache);
 extern void regcache_restore (struct regcache *regcache);
-extern void regcache_restore_no_writethrough (struct regcache *regcache);
 extern struct regcache *regcache_dup (struct regcache *regcache);
+extern void regcache_save_no_passthrough (struct regcache *regcache);
+extern void regcache_restore_no_passthrough (struct regcache *regcache);
+extern struct regcache *regcache_dup_no_passthrough (struct regcache *regcache);
+extern void regcache_move (struct regcache *dest, struct regcache *src);
+extern void regcache_move_no_passthrough (struct regcache *dest, struct regcache *src);
 
 extern char *grub_around_regcache_for_registers (struct regcache *);
 extern char *grub_around_regcache_for_register_valid (struct regcache *);