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.
This commit is contained in:
parent
0ce1b11887
commit
5602984a0d
3 changed files with 66 additions and 33 deletions
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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. */
|
||||
/* 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. */
|
||||
|
||||
extern void regcache_save (struct regcache *dst, struct regcache *src);
|
||||
extern void regcache_restore (struct regcache *dst, struct regcache *src);
|
||||
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
|
||||
|
|
Loading…
Reference in a new issue