cache can only be updated via the methods regcache_dup() and
regcache_cpy(). The actual contents are determined by the
reggroup_save and reggroup_restore methods. */
- int readonly_p;
+ bool readonly_p;
/* If this is a read-write cache, which thread's registers is
it connected to? */
ptid_t ptid;
};
+/* See regcache.h. */
+
+ptid_t
+regcache_get_ptid (const struct regcache *regcache)
+{
+ gdb_assert (!ptid_equal (regcache->ptid, minus_one_ptid));
+
+ return regcache->ptid;
+}
+
static struct regcache *
regcache_xmalloc_1 (struct gdbarch *gdbarch, struct address_space *aspace,
- int readonly_p)
+ bool readonly_p)
{
struct regcache_descr *descr;
struct regcache *regcache;
struct regcache *
regcache_xmalloc (struct gdbarch *gdbarch, struct address_space *aspace)
{
- return regcache_xmalloc_1 (gdbarch, aspace, 1);
+ return regcache_xmalloc_1 (gdbarch, aspace, true);
}
void
}
static void
-regcache_restore (struct regcache *dst,
- regcache_cooked_read_ftype *cooked_read,
- void *cooked_read_context)
+regcache_restore (struct regcache *dst, struct regcache *src)
{
struct gdbarch *gdbarch = dst->descr->gdbarch;
- gdb_byte buf[MAX_REGISTER_SIZE];
int regnum;
/* 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 .. gdbarch_num_regs
+ gdbarch_num_pseudo_regs) range is checked since some architectures need
{
if (gdbarch_register_reggroup_p (gdbarch, regnum, restore_reggroup))
{
- enum register_status status;
-
- status = cooked_read (cooked_read_context, regnum, buf);
- if (status == REG_VALID)
- regcache_cooked_write (dst, regnum, buf);
+ if (src->register_status[regnum] == REG_VALID)
+ regcache_cooked_write (dst, regnum, register_buffer (src, regnum));
}
}
}
if (!src->readonly_p)
regcache_save (dst, do_cooked_read, src);
else if (!dst->readonly_p)
- regcache_restore (dst, do_cooked_read, src);
+ regcache_restore (dst, src);
else
regcache_cpy_no_passthrough (dst, src);
}
&& get_regcache_arch (list->regcache) == gdbarch)
return list->regcache;
- new_regcache = regcache_xmalloc_1 (gdbarch, aspace, 0);
+ new_regcache = regcache_xmalloc_1 (gdbarch, aspace, false);
new_regcache->ptid = ptid;
list = XNEW (struct regcache_list);
alloca (0);
}
-enum register_status
-regcache_raw_read (struct regcache *regcache, int regnum, gdb_byte *buf)
+void
+regcache_raw_update (struct regcache *regcache, int regnum)
{
- gdb_assert (regcache != NULL && buf != NULL);
+ gdb_assert (regcache != NULL);
gdb_assert (regnum >= 0 && regnum < regcache->descr->nr_raw_registers);
+
/* Make certain that the register cache is up-to-date with respect
to the current thread. This switching shouldn't be necessary
only there is still only one target side register cache. Sigh!
On the bright side, at least there is a regcache object. */
+
if (!regcache->readonly_p
&& regcache_register_status (regcache, regnum) == REG_UNKNOWN)
{
- struct cleanup *old_chain = save_inferior_ptid ();
-
- inferior_ptid = regcache->ptid;
target_fetch_registers (regcache, regnum);
- do_cleanups (old_chain);
/* A number of targets can't access the whole set of raw
registers (because the debug API provides no means to get at
if (regcache->register_status[regnum] == REG_UNKNOWN)
regcache->register_status[regnum] = REG_UNAVAILABLE;
}
+}
+
+enum register_status
+regcache_raw_read (struct regcache *regcache, int regnum, gdb_byte *buf)
+{
+ gdb_assert (buf != NULL);
+ regcache_raw_update (regcache, regnum);
if (regcache->register_status[regnum] != REG_VALID)
memset (buf, 0, regcache->descr->sizeof_register[regnum]);
regcache_raw_write (struct regcache *regcache, int regnum,
const gdb_byte *buf)
{
- struct cleanup *chain_before_save_inferior;
- struct cleanup *chain_before_invalidate_register;
+ struct cleanup *old_chain;
gdb_assert (regcache != NULL && buf != NULL);
gdb_assert (regnum >= 0 && regnum < regcache->descr->nr_raw_registers);
regcache->descr->sizeof_register[regnum]) == 0))
return;
- chain_before_save_inferior = save_inferior_ptid ();
- inferior_ptid = regcache->ptid;
-
target_prepare_to_store (regcache);
regcache_raw_set_cached_value (regcache, regnum, buf);
/* Register a cleanup function for invalidating the register after it is
written, in case of a failure. */
- chain_before_invalidate_register
- = make_cleanup_regcache_invalidate (regcache, regnum);
+ old_chain = make_cleanup_regcache_invalidate (regcache, regnum);
target_store_registers (regcache, regnum);
/* The target did not throw an error so we can discard invalidating the
register and restore the cleanup chain to what it was. */
- discard_cleanups (chain_before_invalidate_register);
-
- do_cleanups (chain_before_save_inferior);
+ discard_cleanups (old_chain);
}
void
const gdb_byte *buf))
{
struct regcache_descr *descr = regcache->descr;
- gdb_byte reg[MAX_REGISTER_SIZE];
+ struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ gdb_byte *reg = (gdb_byte *) alloca (register_size (gdbarch, regnum));
gdb_assert (offset >= 0 && offset <= descr->sizeof_register[regnum]);
gdb_assert (len >= 0 && offset + len <= descr->sizeof_register[regnum]);
reinit_frame_cache ();
}
+void
+regcache_debug_print_register (const char *func, struct regcache *regcache,
+ int regno)
+{
+ struct gdbarch *gdbarch = get_regcache_arch (regcache);
+
+ fprintf_unfiltered (gdb_stdlog, "%s ", func);
+ if (regno >= 0 && regno < gdbarch_num_regs (gdbarch)
+ && gdbarch_register_name (gdbarch, regno) != NULL
+ && gdbarch_register_name (gdbarch, regno)[0] != '\0')
+ fprintf_unfiltered (gdb_stdlog, "(%s)",
+ gdbarch_register_name (gdbarch, regno));
+ else
+ fprintf_unfiltered (gdb_stdlog, "(%d)", regno);
+ if (regno >= 0 && regno < gdbarch_num_regs (gdbarch))
+ {
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+ int size = register_size (gdbarch, regno);
+ gdb_byte *buf = register_buffer (regcache, regno);
+
+ fprintf_unfiltered (gdb_stdlog, " = ");
+ for (int i = 0; i < size; i++)
+ {
+ fprintf_unfiltered (gdb_stdlog, "%02x", buf[i]);
+ }
+ if (size <= sizeof (LONGEST))
+ {
+ ULONGEST val = extract_unsigned_integer (buf, size, byte_order);
+
+ fprintf_unfiltered (gdb_stdlog, " %s %s",
+ core_addr_to_string_nz (val), plongest (val));
+ }
+ }
+ fprintf_unfiltered (gdb_stdlog, "\n");
+}
static void
reg_flush_command (char *command, int from_tty)
regcache_dump (get_current_regcache (), gdb_stdout, what_to_dump);
else
{
- struct cleanup *cleanups;
- struct ui_file *file = gdb_fopen (args, "w");
+ stdio_file file;
- if (file == NULL)
+ if (!file.open (args, "w"))
perror_with_name (_("maintenance print architecture"));
- cleanups = make_cleanup_ui_file_delete (file);
- regcache_dump (get_current_regcache (), file, what_to_dump);
- do_cleanups (cleanups);
+ regcache_dump (get_current_regcache (), &file, what_to_dump);
}
}