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>
|
||||
|
||||
* 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);
|
||||
}
|
||||
|
||||
/* 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. */
|
||||
|
||||
ULONGEST
|
||||
|
@ -1439,7 +1528,12 @@ regcache_dump (struct regcache *regcache, struct ui_file *file,
|
|||
fprintf_unfiltered (file, " %6ld",
|
||||
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)
|
||||
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);
|
||||
|
||||
|
||||
/* 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
|
||||
then its gdbarch vector counterpart since it returns a precomputed
|
||||
value stored in a table.
|
||||
|
|
Loading…
Reference in a new issue