This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
[PATCH]: Enable pseudo-registers in GDB.
- To: gdb-patches at sourceware dot cygnus dot com
- Subject: [PATCH]: Enable pseudo-registers in GDB.
- From: Michael Snyder <msnyder at cygnus dot com>
- Date: Wed, 12 Jul 2000 15:00:08 -0700 (PDT)
OK, here is the patch.
The way you use this is:
1) You define NUM_PSEUDO_REGS to the number of pseudo-registers.
2) Add names of your pseudo-regs to THE END OF the register_names.
3) Add the number of bytes of storage that you require for your
pseudo-registers to REGISTER_BYTES. Note -- pseudo-regs that
are just aliases for previously existing regs do not need any
additional storage.
4) Add handling for your pseudo-regs to REGISTER_VIRTUAL_TYPE,
REGISTER_BYTE, REGISTER_RAW_SIZE, etc. Note that for an alias
register, REGISTER_BYTE should return the same offset as the
real register for which this one is an alias.
5) Define ARCH_FETCH_PSEUDO_REGISTERS(regno) and
ARCH_STORE_PSEUDO_REGISTERS(regno) to compute (or whatever)
the values for your pseudo-registers. These will probably be
defined in your tm.h and live in your -tdep.c file.
I will provide an example in a subsequent email.
2000-07-12 Michael Snyder <msnyder@cleaver.cygnus.com>
This change adds pseudo-register capability to GDB.
Pseudo-registers are handled like registers, but they
don't come from or live on the target. They may be
aliases for an existing register, or they may be computed.
* defs.h (NUM_PSEUDO_REGISTERS): Define default of zero.
(ARCH_FETCH_PSEUDO_REGISTERS): Define default of no-op.
(ARCH_STORE_PSEUDO_REGISTERS): Define default of no-op.
# regcache.c (registers_changed): Mark pseudo-registers
invalid, as well as real registers.
(registers_fetched): Do not mark pseudo-registers as fetched
at the same time as other (real) registers.
(read_register_bytes): Fetch pseudo-registers (if any) from
the target architecture module instead of from the target.
(read_register_gen): Ditto.
(read_register): Ditto.
(write_register_bytes): Store pseudo-registers (if any) to
the target architecture module instead of to the target.
(write_register_gen): Ditto.
(write_register): Ditto.
(build_regcache): Allocate enough register_valid space for
pseudo-registers as well as normal (real) ones.
Index: regcache.c
===================================================================
RCS file: /cvs/src/src/gdb/regcache.c,v
retrieving revision 1.3
diff -p -r1.3 regcache.c
*** regcache.c 2000/07/11 05:42:25 1.3
--- regcache.c 2000/07/12 21:52:50
*************** void
*** 282,288 ****
registers_changed (void)
{
int i;
- int numregs = ARCH_NUM_REGS;
registers_pid = -1;
--- 282,287 ----
*************** registers_changed (void)
*** 293,301 ****
gdb gives control to the user (ie watchpoints). */
alloca (0);
! for (i = 0; i < numregs; i++)
register_valid[i] = 0;
if (registers_changed_hook)
registers_changed_hook ();
}
--- 292,305 ----
gdb gives control to the user (ie watchpoints). */
alloca (0);
! for (i = 0; i < ARCH_NUM_REGS; i++)
register_valid[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++)
+ register_valid[i] = 0;
+
if (registers_changed_hook)
registers_changed_hook ();
}
*************** void
*** 309,318 ****
registers_fetched (void)
{
int i;
- int numregs = ARCH_NUM_REGS;
! for (i = 0; i < numregs; i++)
register_valid[i] = 1;
}
/* read_register_bytes and write_register_bytes are generally a *BAD*
--- 313,323 ----
registers_fetched (void)
{
int i;
! for (i = 0; i < ARCH_NUM_REGS; i++)
register_valid[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*
*************** read_register_bytes (int inregbyte, char
*** 351,357 ****
/* See if we are trying to read bytes from out-of-date registers. If so,
update just those registers. */
! for (regno = 0; regno < NUM_REGS; regno++)
{
int regstart, regend;
--- 356,362 ----
/* See if we are trying to read bytes from out-of-date registers. If so,
update just those registers. */
! for (regno = 0; regno < NUM_REGS + NUM_PSEUDO_REGS; regno++)
{
int regstart, regend;
*************** read_register_bytes (int inregbyte, char
*** 368,376 ****
/* The range the user wants to read doesn't overlap with regno. */
continue;
! /* We've found an invalid register where at least one byte will be read.
Update it from the target. */
! target_fetch_registers (regno);
if (!register_valid[regno])
error ("read_register_bytes: Couldn't update register %d.", regno);
--- 373,384 ----
/* The range the user wants to read doesn't overlap with regno. */
continue;
! /* We've found an uncached register where at least one byte will be read.
Update it from the target. */
! if (regno < NUM_REGS)
! target_fetch_registers (regno);
! else if (regno < NUM_PSEUDO_REGS)
! ARCH_FETCH_PSEUDO_REGISTERS (regno);
if (!register_valid[regno])
error ("read_register_bytes: Couldn't update register %d.", regno);
*************** read_register_gen (int regno, char *myad
*** 395,401 ****
}
if (!register_valid[regno])
! target_fetch_registers (regno);
memcpy (myaddr, ®isters[REGISTER_BYTE (regno)],
REGISTER_RAW_SIZE (regno));
}
--- 403,414 ----
}
if (!register_valid[regno])
! {
! if (regno < NUM_REGS)
! target_fetch_registers (regno);
! else if (regno < NUM_REGS + NUM_PSEUDO_REGS)
! ARCH_FETCH_PSEUDO_REGISTERS (regno);
! }
memcpy (myaddr, ®isters[REGISTER_BYTE (regno)],
REGISTER_RAW_SIZE (regno));
}
*************** write_register_gen (int regno, char *mya
*** 433,445 ****
&& memcmp (®isters[REGISTER_BYTE (regno)], myaddr, size) == 0)
return;
! target_prepare_to_store ();
memcpy (®isters[REGISTER_BYTE (regno)], myaddr, size);
register_valid[regno] = 1;
! target_store_registers (regno);
}
/* Copy INLEN bytes of consecutive data from memory at MYADDR
--- 446,462 ----
&& memcmp (®isters[REGISTER_BYTE (regno)], myaddr, size) == 0)
return;
! if (regno < NUM_REGS)
! target_prepare_to_store ();
memcpy (®isters[REGISTER_BYTE (regno)], myaddr, size);
register_valid[regno] = 1;
! if (regno < NUM_REGS)
! target_store_registers (regno);
! else if (regno < NUM_REGS + NUM_PSEUDO_REGS)
! ARCH_STORE_PSEUDO_REGISTERS (regno);
}
/* Copy INLEN bytes of consecutive data from memory at MYADDR
*************** write_register_bytes (int myregstart, ch
*** 458,464 ****
nice things like handling threads, and avoiding updates when the
new and old contents are the same. */
! for (regno = 0; regno < NUM_REGS; regno++)
{
int regstart, regend;
--- 475,481 ----
nice things like handling threads, and avoiding updates when the
new and old contents are the same. */
! for (regno = 0; regno < NUM_REGS + NUM_PSEUDO_REGS; regno++)
{
int regstart, regend;
*************** write_register_bytes (int myregstart, ch
*** 490,496 ****
myaddr + (overlapstart - myregstart),
overlapend - overlapstart);
! target_store_registers (regno);
}
}
}
--- 507,516 ----
myaddr + (overlapstart - myregstart),
overlapend - overlapstart);
! if (regno < NUM_REGS)
! target_store_registers (regno);
! else if (regno < NUM_REGS + NUM_PSEUDO_REGS)
! ARCH_STORE_PSEUDO_REGISTERS (regno);
}
}
}
*************** read_register (int regno)
*** 509,515 ****
}
if (!register_valid[regno])
! target_fetch_registers (regno);
return (extract_unsigned_integer (®isters[REGISTER_BYTE (regno)],
REGISTER_RAW_SIZE (regno)));
--- 529,540 ----
}
if (!register_valid[regno])
! {
! if (regno < NUM_REGS)
! target_fetch_registers (regno);
! else if (regno < NUM_PSEUDO_REGS)
! ARCH_FETCH_PSEUDO_REGISTERS (regno);
! }
return (extract_unsigned_integer (®isters[REGISTER_BYTE (regno)],
REGISTER_RAW_SIZE (regno)));
*************** write_register (int regno, LONGEST val)
*** 604,616 ****
&& memcmp (®isters[REGISTER_BYTE (regno)], buf, size) == 0)
return;
! target_prepare_to_store ();
memcpy (®isters[REGISTER_BYTE (regno)], buf, size);
register_valid[regno] = 1;
! target_store_registers (regno);
}
void
--- 629,645 ----
&& memcmp (®isters[REGISTER_BYTE (regno)], buf, size) == 0)
return;
! if (regno < NUM_REGS)
! target_prepare_to_store ();
memcpy (®isters[REGISTER_BYTE (regno)], buf, size);
register_valid[regno] = 1;
! if (regno < NUM_REGS)
! target_store_registers (regno);
! else if (regno < NUM_REGS + NUM_PSEUDO_REGS)
! ARCH_STORE_PSEUDO_REGISTERS (regno);
}
void
*************** build_regcache (void)
*** 859,865 ****
/* 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 * sizeof (*register_valid);
registers = xmalloc (sizeof_registers);
memset (registers, 0, sizeof_registers);
register_valid = xmalloc (sizeof_register_valid);
--- 888,895 ----
/* 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);