summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Cagney <cagney@redhat.com>2002-05-17 15:06:31 +0000
committerAndrew Cagney <cagney@redhat.com>2002-05-17 15:06:31 +0000
commitd805fddaada440a5a54601622162f37309dd6692 (patch)
tree81b82fc3aea154ae4c68c69d3cccaea10b008f5c
parenta08e2063b932efe324ccc57393daf8ea8e48e379 (diff)
downloadbinutils-gdb-d805fddaada440a5a54601622162f37309dd6692.tar.gz
introduce regcache_move.
Fix cases where normal vs no_passthroug copies didn't reflect the old code.
-rw-r--r--gdb/ChangeLog30
-rw-r--r--gdb/blockframe.c2
-rw-r--r--gdb/infcmd.c2
-rw-r--r--gdb/infrun.c8
-rw-r--r--gdb/regcache.c91
-rw-r--r--gdb/regcache.h11
6 files changed, 114 insertions, 30 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 11bcf3d77f7..742d060137a 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -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".
diff --git a/gdb/blockframe.c b/gdb/blockframe.c
index 477a8a3e2f5..78b31eff438 100644
--- a/gdb/blockframe.c
+++ b/gdb/blockframe.c
@@ -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;
}
diff --git a/gdb/infcmd.c b/gdb/infcmd.c
index 14bb00bda49..ae5d5253902 100644
--- a/gdb/infcmd.c
+++ b/gdb/infcmd.c
@@ -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;
}
diff --git a/gdb/infrun.c b/gdb/infrun.c
index b46779160ed..409fede4d1d 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -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;
diff --git a/gdb/regcache.c b/gdb/regcache.c
index 38f611c63c2..3c9617658e0 100644
--- a/gdb/regcache.c
+++ b/gdb/regcache.c
@@ -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
diff --git a/gdb/regcache.h b/gdb/regcache.h
index 8a209d80553..931393527fc 100644
--- a/gdb/regcache.h
+++ b/gdb/regcache.h
@@ -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 *);