2002-08-25 Andrew Cagney <ac131313@redhat.com>
* regcache.h (register_offset_hack): Declare. (regcache_cooked_read_using_offset_hack): Declare. (regcache_cooked_write_using_offset_hack): Declare. * regcache.c (register_offset_hack): New function. (regcache_cooked_read_using_offset_hack): New function. (regcache_cooked_write_using_offset_hack): New function. (regcache_dump): Check that the registers, according to their offset, are packed hard against each other. (cooked_xfer_using_offset_hack): New function.
This commit is contained in:
parent
90949d06a3
commit
d3b22ed57c
3 changed files with 135 additions and 1 deletions
|
@ -1,3 +1,16 @@
|
||||||
|
2002-08-25 Andrew Cagney <ac131313@redhat.com>
|
||||||
|
|
||||||
|
* regcache.h (register_offset_hack): Declare.
|
||||||
|
(regcache_cooked_read_using_offset_hack): Declare.
|
||||||
|
(regcache_cooked_write_using_offset_hack): Declare.
|
||||||
|
|
||||||
|
* regcache.c (register_offset_hack): New function.
|
||||||
|
(regcache_cooked_read_using_offset_hack): New function.
|
||||||
|
(regcache_cooked_write_using_offset_hack): New function.
|
||||||
|
(regcache_dump): Check that the registers, according to their
|
||||||
|
offset, are packed hard against each other.
|
||||||
|
(cooked_xfer_using_offset_hack): New function.
|
||||||
|
|
||||||
2002-08-25 Andrew Cagney <ac131313@redhat.com>
|
2002-08-25 Andrew Cagney <ac131313@redhat.com>
|
||||||
|
|
||||||
* regcache.c (struct regcache_descr): Add field register_type.
|
* regcache.c (struct regcache_descr): Add field register_type.
|
||||||
|
|
|
@ -1029,6 +1029,95 @@ regcache_cooked_write_part (struct regcache *regcache, int regnum,
|
||||||
regcache_cooked_read, regcache_cooked_write);
|
regcache_cooked_read, regcache_cooked_write);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Hack to keep code that view the register buffer as raw bytes
|
||||||
|
working. */
|
||||||
|
|
||||||
|
int
|
||||||
|
register_offset_hack (struct gdbarch *gdbarch, int regnum)
|
||||||
|
{
|
||||||
|
struct regcache_descr *descr = regcache_descr (gdbarch);
|
||||||
|
gdb_assert (regnum >= 0 && regnum < descr->nr_cooked_registers);
|
||||||
|
return descr->register_offset[regnum];
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cooked_xfer_using_offset_hack (struct regcache *regcache,
|
||||||
|
int buf_start, int buf_len, void *in_b,
|
||||||
|
const void *out_b)
|
||||||
|
{
|
||||||
|
struct regcache_descr *descr = regcache->descr;
|
||||||
|
struct gdbarch *gdbarch = descr->gdbarch;
|
||||||
|
bfd_byte *in_buf = in_b;
|
||||||
|
const bfd_byte *out_buf = out_b;
|
||||||
|
int buf_end = buf_start + buf_len;
|
||||||
|
int regnum;
|
||||||
|
char *reg_buf = alloca (descr->max_register_size);
|
||||||
|
|
||||||
|
/* NOTE: cagney/2002-08-17: This code assumes that the register
|
||||||
|
offsets are strictly increasing and do not overlap. If this
|
||||||
|
isn't the case then the bug is in the target architecture and NOT
|
||||||
|
this code. */
|
||||||
|
|
||||||
|
/* NOTE: cagney/2002-08-17: This code assumes that only the
|
||||||
|
registers covered by BUF_START:BUF_LEN should be transfered. If,
|
||||||
|
for some reason, there is a gap between two registers, then that
|
||||||
|
gap isn't transfered. (The gap shouldn't be there but that is
|
||||||
|
another story.) */
|
||||||
|
|
||||||
|
/* Iterate through all registers looking for those that lie within
|
||||||
|
BUF_START:BUF_LEN. */
|
||||||
|
|
||||||
|
for (regnum = 0; regnum < descr->nr_cooked_registers; regnum++)
|
||||||
|
{
|
||||||
|
/* The register's location. */
|
||||||
|
int reg_start = descr->register_offset[regnum];
|
||||||
|
int reg_len = descr->sizeof_register[regnum];
|
||||||
|
int reg_end = reg_start + reg_len;
|
||||||
|
|
||||||
|
/* The START, END and LEN that falls within the current
|
||||||
|
register. */
|
||||||
|
int xfer_start;
|
||||||
|
int xfer_end;
|
||||||
|
int xfer_len;
|
||||||
|
|
||||||
|
/* start = max (reg_start, buf_start) */
|
||||||
|
if (reg_start > buf_start)
|
||||||
|
xfer_start = reg_start;
|
||||||
|
else
|
||||||
|
xfer_start = buf_start;
|
||||||
|
|
||||||
|
/* end = min (reg_end, buf_end) */
|
||||||
|
if (reg_end < buf_end)
|
||||||
|
xfer_end = reg_end;
|
||||||
|
else
|
||||||
|
xfer_end = buf_end;
|
||||||
|
|
||||||
|
/* The number of bytes to transfer. If there isn't anything to
|
||||||
|
transfer (the end is before the start) this will be -ve. */
|
||||||
|
xfer_len = xfer_end - xfer_start;
|
||||||
|
|
||||||
|
if (xfer_len > 0)
|
||||||
|
regcache_xfer_part (regcache, regnum, xfer_start - reg_start,
|
||||||
|
xfer_len, in_b, out_b, regcache_cooked_read,
|
||||||
|
regcache_cooked_write);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
regcache_cooked_read_using_offset_hack (struct regcache *regcache,
|
||||||
|
int buf_start, int buf_len, void *b)
|
||||||
|
{
|
||||||
|
cooked_xfer_using_offset_hack (regcache, buf_start, buf_len, b, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
regcache_cooked_write_using_offset_hack (struct regcache *regcache,
|
||||||
|
int buf_start, int buf_len,
|
||||||
|
const void *b)
|
||||||
|
{
|
||||||
|
cooked_xfer_using_offset_hack (regcache, buf_start, buf_len, NULL, b);
|
||||||
|
}
|
||||||
|
|
||||||
/* Return the contents of register REGNUM as an unsigned integer. */
|
/* Return the contents of register REGNUM as an unsigned integer. */
|
||||||
|
|
||||||
ULONGEST
|
ULONGEST
|
||||||
|
@ -1439,7 +1528,12 @@ regcache_dump (struct regcache *regcache, struct ui_file *file,
|
||||||
fprintf_unfiltered (file, " %6ld",
|
fprintf_unfiltered (file, " %6ld",
|
||||||
regcache->descr->register_offset[regnum]);
|
regcache->descr->register_offset[regnum]);
|
||||||
if (register_offset != regcache->descr->register_offset[regnum]
|
if (register_offset != regcache->descr->register_offset[regnum]
|
||||||
|| register_offset != REGISTER_BYTE (regnum))
|
|| register_offset != REGISTER_BYTE (regnum)
|
||||||
|
|| (regnum > 0
|
||||||
|
&& (regcache->descr->register_offset[regnum]
|
||||||
|
!= (regcache->descr->register_offset[regnum - 1]
|
||||||
|
+ regcache->descr->sizeof_register[regnum - 1])))
|
||||||
|
)
|
||||||
{
|
{
|
||||||
if (!footnote_register_offset)
|
if (!footnote_register_offset)
|
||||||
footnote_register_offset = ++footnote_nr;
|
footnote_register_offset = ++footnote_nr;
|
||||||
|
|
|
@ -88,6 +88,33 @@ extern void supply_register (int regnum, const void *val);
|
||||||
extern void regcache_collect (int regnum, void *buf);
|
extern void regcache_collect (int regnum, void *buf);
|
||||||
|
|
||||||
|
|
||||||
|
/* The register's ``offset''.
|
||||||
|
|
||||||
|
NOTE: cagney/2002-08-17: The ``struct value'' and expression
|
||||||
|
evaluator treat the register cache as a large liner buffer.
|
||||||
|
Instead of reading/writing a register using its register number,
|
||||||
|
the code read/writes registers by specifying their offset into the
|
||||||
|
buffer and a number of bytes. The code also assumes that these
|
||||||
|
byte read/writes can cross register boundaries, adjacent registers
|
||||||
|
treated as a contiguous set of bytes.
|
||||||
|
|
||||||
|
The below map that model onto the real register cache. New code
|
||||||
|
should go out of their way to avoid using these interfaces.
|
||||||
|
|
||||||
|
FIXME: cagney/2002-08-17: The ``struct value'' and expression
|
||||||
|
evaluator should be fixed. Instead of using the { offset, length }
|
||||||
|
pair to describe a value within one or more registers, the code
|
||||||
|
should use a chain of { regnum, offset, len } tripples. */
|
||||||
|
|
||||||
|
extern int register_offset_hack (struct gdbarch *gdbarch, int regnum);
|
||||||
|
extern void regcache_cooked_read_using_offset_hack (struct regcache *regcache,
|
||||||
|
int offset, int len,
|
||||||
|
void *buf);
|
||||||
|
extern void regcache_cooked_write_using_offset_hack (struct regcache *regcache,
|
||||||
|
int offset, int len,
|
||||||
|
const void *buf);
|
||||||
|
|
||||||
|
|
||||||
/* The type of a register. This function is slightly more efficient
|
/* The type of a register. This function is slightly more efficient
|
||||||
then its gdbarch vector counterpart since it returns a precomputed
|
then its gdbarch vector counterpart since it returns a precomputed
|
||||||
value stored in a table.
|
value stored in a table.
|
||||||
|
|
Loading…
Reference in a new issue