This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
[patch] Allow all NUM_REGS + NUM_PSEUDO_REGS in the regcache
- From: Andrew Cagney <ac131313 at cygnus dot com>
- To: gdb-patches at sources dot redhat dot com
- Date: Tue, 04 Dec 2001 17:57:25 -0500
- Subject: [patch] Allow all NUM_REGS + NUM_PSEUDO_REGS in the regcache
Hello,
Following up a proposal in gdb@, the attatched patch adjusts regcache so
that it is tolerant of raw registers in the range
[0..NUM_REGS+NUM_PSEUDO_REGS).
remote.c is next.
look ok?
Andrew
2001-12-04 Andrew Cagney <ac131313@redhat.com>
* regcache.c (store_register, fetch_register): Only use fetch/store
pseudo-register when function is present. Assume target can
handle all registers.
(registers_changed): Simplify invalidate loop.
(registers_fetched): Add comments.
(register_buffer): Add regnum range assertion. Remove code
handling -ve regnum.
(build_regcache): Make space for pseudo-registers when computing
sizeof_registers. Initialize register_offset.
* gdbarch.sh (FETCH_PSEUDO_REGISTER): Change to a function with
predicate.
(STORE_PSEUDO_REGISTER): Ditto.
* gdbarch.h, gdbarch.c: Re-generate.
Index: gdbarch.sh
===================================================================
RCS file: /cvs/src/src/gdb/gdbarch.sh,v
retrieving revision 1.93
diff -p -r1.93 gdbarch.sh
*** gdbarch.sh 2001/11/22 00:23:12 1.93
--- gdbarch.sh 2001/12/04 22:32:19
*************** f:2:REGISTER_CONVERT_TO_RAW:void:registe
*** 468,478 ****
# This function is called when the value of a pseudo-register needs to
# be updated. Typically it will be defined on a per-architecture
# basis.
! f:2:FETCH_PSEUDO_REGISTER:void:fetch_pseudo_register:int regnum:regnum:::0::0
# This function is called when the value of a pseudo-register needs to
# be set or stored. Typically it will be defined on a
# per-architecture basis.
! f:2:STORE_PSEUDO_REGISTER:void:store_pseudo_register:int regnum:regnum:::0::0
#
f:2:POINTER_TO_ADDRESS:CORE_ADDR:pointer_to_address:struct type *type, void *buf:type, buf:::unsigned_pointer_to_address::0
f:2:ADDRESS_TO_POINTER:void:address_to_pointer:struct type *type, void *buf, CORE_ADDR addr:type, buf, addr:::unsigned_address_to_pointer::0
--- 468,478 ----
# This function is called when the value of a pseudo-register needs to
# be updated. Typically it will be defined on a per-architecture
# basis.
! F:2:FETCH_PSEUDO_REGISTER:void:fetch_pseudo_register:int regnum:regnum:
# This function is called when the value of a pseudo-register needs to
# be set or stored. Typically it will be defined on a
# per-architecture basis.
! F:2:STORE_PSEUDO_REGISTER:void:store_pseudo_register:int regnum:regnum:
#
f:2:POINTER_TO_ADDRESS:CORE_ADDR:pointer_to_address:struct type *type, void *buf:type, buf:::unsigned_pointer_to_address::0
f:2:ADDRESS_TO_POINTER:void:address_to_pointer:struct type *type, void *buf, CORE_ADDR addr:type, buf, addr:::unsigned_address_to_pointer::0
Index: regcache.c
===================================================================
RCS file: /cvs/src/src/gdb/regcache.c,v
retrieving revision 1.27
diff -p -r1.27 regcache.c
*** regcache.c 2001/11/15 06:43:10 1.27
--- regcache.c 2001/12/04 22:32:20
*************** register_changed (int regnum)
*** 93,102 ****
static char *
register_buffer (int regnum)
{
! if (regnum < 0)
! return registers;
! else
! return ®isters[REGISTER_BYTE (regnum)];
}
/* Return whether register REGNUM is a real register. */
--- 93,100 ----
static char *
register_buffer (int regnum)
{
! gdb_assert (regnum >= 0 && regnum < (NUM_REGS + NUM_PSEUDO_REGS));
! return ®isters[REGISTER_BYTE (regnum)];
}
/* Return whether register REGNUM is a real register. */
*************** pseudo_register (int regnum)
*** 120,129 ****
static void
fetch_register (int regnum)
{
! if (real_register (regnum))
! target_fetch_registers (regnum);
! else if (pseudo_register (regnum))
FETCH_PSEUDO_REGISTER (regnum);
}
/* Write register REGNUM cached value to the target. */
--- 118,131 ----
static void
fetch_register (int regnum)
{
! /* NOTE: cagney/2001-12-04: Legacy targets were using fetch/store
! pseudo-register as a way of handling registers that needed to be
! constructed from one or more raw registers. New targets instead
! use gdbarch register read/write. */
! if (FETCH_PSEUDO_REGISTER_P ()
! && pseudo_register (regnum))
FETCH_PSEUDO_REGISTER (regnum);
+ target_fetch_registers (regnum);
}
/* Write register REGNUM cached value to the target. */
*************** fetch_register (int regnum)
*** 131,140 ****
static void
store_register (int regnum)
{
! if (real_register (regnum))
! target_store_registers (regnum);
! else if (pseudo_register (regnum))
STORE_PSEUDO_REGISTER (regnum);
}
/* Low level examining and depositing of registers.
--- 133,146 ----
static void
store_register (int regnum)
{
! /* NOTE: cagney/2001-12-04: Legacy targets were using fetch/store
! pseudo-register as a way of handling registers that needed to be
! constructed from one or more raw registers. New targets instead
! use gdbarch register read/write. */
! if (STORE_PSEUDO_REGISTER_P ()
! && pseudo_register (regnum))
STORE_PSEUDO_REGISTER (regnum);
+ target_store_registers (regnum);
}
/* Low level examining and depositing of registers.
*************** registers_changed (void)
*** 162,175 ****
gdb gives control to the user (ie watchpoints). */
alloca (0);
! for (i = 0; i < NUM_REGS; i++)
set_register_cached (i, 0);
- /* Assume that if all the hardware regs have changed,
- then so have the pseudo-registers. */
- for (i = NUM_REGS; i < NUM_REGS + NUM_PSEUDO_REGS; i++)
- set_register_cached (i, 0);
-
if (registers_changed_hook)
registers_changed_hook ();
}
--- 168,176 ----
gdb gives control to the user (ie watchpoints). */
alloca (0);
! for (i = 0; i < NUM_REGS + NUM_PSEUDO_REGS; i++)
set_register_cached (i, 0);
if (registers_changed_hook)
registers_changed_hook ();
}
*************** registers_changed (void)
*** 178,183 ****
--- 179,191 ----
Indicate that all registers have been fetched, so mark them all valid. */
+ /* NOTE: cagney/2001-12-04: This function does not set valid on the
+ pseudo-register range since pseudo registers are always supplied
+ using supply_register(). */
+ /* FIXME: cagney/2001-12-04: This function is DEPRECATED. The target
+ code was blatting the registers[] array and then calling this.
+ Since targets should only be using supply_register() the need for
+ this function/hack is eliminated. */
void
registers_fetched (void)
*************** registers_fetched (void)
*** 187,193 ****
for (i = 0; i < NUM_REGS; i++)
set_register_cached (i, 1);
/* Do not assume that the pseudo-regs have also been fetched.
! Fetching all real regs might not account for all pseudo-regs. */
}
/* read_register_bytes and write_register_bytes are generally a *BAD*
--- 195,201 ----
for (i = 0; i < NUM_REGS; i++)
set_register_cached (i, 1);
/* Do not assume that the pseudo-regs have also been fetched.
! Fetching all real regs NEVER accounts for pseudo-regs. */
}
/* read_register_bytes and write_register_bytes are generally a *BAD*
*************** reg_flush_command (char *command, int fr
*** 758,774 ****
printf_filtered ("Register cache flushed.\n");
}
static void
build_regcache (void)
{
! /* We allocate some extra slop since we do a lot of memcpy's around
! `registers', and failing-soft is better than failing hard. */
! int sizeof_registers = REGISTER_BYTES + /* SLOP */ 256;
! int sizeof_register_valid =
! (NUM_REGS + NUM_PSEUDO_REGS) * sizeof (*register_valid);
registers = xmalloc (sizeof_registers);
! memset (registers, 0, sizeof_registers);
register_valid = xmalloc (sizeof_register_valid);
memset (register_valid, 0, sizeof_register_valid);
}
--- 766,801 ----
printf_filtered ("Register cache flushed.\n");
}
+ #undef XCALLOC
+ #define XCALLOC(NR,TYPE) ((TYPE*) xcalloc ((NR), sizeof (TYPE)))
static void
build_regcache (void)
{
! int i;
! int sizeof_register_valid;
! /* Come up with the real size of the registers buffer. */
! int sizeof_registers = REGISTER_BYTES; /* OK use. */
! for (i = 0; i < NUM_REGS + NUM_PSEUDO_REGS; i++)
! {
! long regend;
! /* Keep extending the buffer so that there is always enough
! space for all registers. The comparison is necessary since
! legacy code is free to put registers in random places in the
! buffer separated by holes. Once REGISTER_BYTE() is killed
! this can be greatly simplified. */
! /* FIXME: cagney/2001-12-04: This code shouldn't need to use
! REGISTER_BYTE(). Unfortunatly, legacy code likes to lay the
! buffer out so that certain registers just happen to overlap.
! Ulgh! New targets use gdbarch's register read/write and
! entirely avoid this uglyness. */
! regend = REGISTER_BYTE (i) + REGISTER_RAW_SIZE (i);
! if (sizeof_registers < regend)
! sizeof_registers = regend;
! }
registers = xmalloc (sizeof_registers);
! sizeof_register_valid = ((NUM_REGS + NUM_PSEUDO_REGS)
! * sizeof (*register_valid));
register_valid = xmalloc (sizeof_register_valid);
memset (register_valid, 0, sizeof_register_valid);
}