#include "inferior.h"
#include "target.h"
#include "gdbarch.h"
+#include "gdbcmd.h"
/*
* DATA STRUCTURE
return register_valid[regnum];
}
+/* REGISTER_CHANGED
+
+ invalidate a single register REGNUM in the cache */
+void
+register_changed (int regnum)
+{
+ register_valid[regnum] = 0;
+}
+
/* FIND_SAVED_REGISTER ()
Return the address in which frame FRAME's value of register REGNUM
registers_changed (void)
{
int i;
- int numregs = ARCH_NUM_REGS;
registers_pid = -1;
gdb gives control to the user (ie watchpoints). */
alloca (0);
- for (i = 0; i < numregs; i++)
+ 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_fetched (void)
{
int i;
- int numregs = ARCH_NUM_REGS;
- for (i = 0; i < numregs; 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*
/* 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++)
+ for (regno = 0; regno < NUM_REGS + NUM_PSEUDO_REGS; regno++)
{
int regstart, regend;
/* 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.
+ /* We've found an uncached register where at least one byte will be read.
Update it from the target. */
- target_fetch_registers (regno);
+ if (regno < NUM_REGS)
+ target_fetch_registers (regno);
+ else if (regno < NUM_REGS + NUM_PSEUDO_REGS)
+ FETCH_PSEUDO_REGISTER (regno);
if (!register_valid[regno])
- error ("read_register_bytes: Couldn't update register %d.", regno);
+ {
+ /* Sometimes pseudoregs are never marked valid, so that they
+ will be fetched every time (it can be complicated to know
+ if a pseudoreg is valid, while "fetching" them can be cheap).
+ */
+ if (regno < NUM_REGS)
+ error ("read_register_bytes: Couldn't update register %d.", regno);
+ }
}
if (myaddr != NULL)
}
if (!register_valid[regno])
- target_fetch_registers (regno);
+ {
+ if (regno < NUM_REGS)
+ target_fetch_registers (regno);
+ else if (regno < NUM_REGS + NUM_PSEUDO_REGS)
+ FETCH_PSEUDO_REGISTER (regno);
+ }
memcpy (myaddr, ®isters[REGISTER_BYTE (regno)],
REGISTER_RAW_SIZE (regno));
}
&& memcmp (®isters[REGISTER_BYTE (regno)], myaddr, size) == 0)
return;
- target_prepare_to_store ();
+ if (regno < NUM_REGS)
+ target_prepare_to_store ();
memcpy (®isters[REGISTER_BYTE (regno)], myaddr, size);
register_valid[regno] = 1;
- target_store_registers (regno);
+ if (regno < NUM_REGS)
+ target_store_registers (regno);
+ else if (regno < NUM_REGS + NUM_PSEUDO_REGS)
+ STORE_PSEUDO_REGISTER (regno);
}
/* Copy INLEN bytes of consecutive data from memory at MYADDR
nice things like handling threads, and avoiding updates when the
new and old contents are the same. */
- for (regno = 0; regno < NUM_REGS; regno++)
+ for (regno = 0; regno < NUM_REGS + NUM_PSEUDO_REGS; regno++)
{
int regstart, regend;
myaddr + (overlapstart - myregstart),
overlapend - overlapstart);
- target_store_registers (regno);
+ if (regno < NUM_REGS)
+ target_store_registers (regno);
+ else if (regno < NUM_REGS + NUM_PSEUDO_REGS)
+ STORE_PSEUDO_REGISTER (regno);
}
}
}
/* Return the raw contents of register REGNO, regarding it as an
- integer. This probably should be returning LONGEST rather than
- CORE_ADDR. */
+ UNSIGNED integer. */
-CORE_ADDR
+ULONGEST
read_register (int regno)
{
if (registers_pid != inferior_pid)
}
if (!register_valid[regno])
- target_fetch_registers (regno);
+ {
+ if (regno < NUM_REGS)
+ target_fetch_registers (regno);
+ else if (regno < NUM_REGS + NUM_PSEUDO_REGS)
+ FETCH_PSEUDO_REGISTER (regno);
+ }
- return ((CORE_ADDR)
- extract_unsigned_integer (®isters[REGISTER_BYTE (regno)],
+ return (extract_unsigned_integer (®isters[REGISTER_BYTE (regno)],
REGISTER_RAW_SIZE (regno)));
}
-CORE_ADDR
+ULONGEST
read_register_pid (int regno, int pid)
{
int save_pid;
return retval;
}
+/* Return the raw contents of register REGNO, regarding it a SIGNED
+ integer. */
+
+LONGEST
+read_signed_register (int regno)
+{
+ if (registers_pid != inferior_pid)
+ {
+ registers_changed ();
+ registers_pid = inferior_pid;
+ }
+
+ if (!register_valid[regno])
+ target_fetch_registers (regno);
+
+ return (extract_signed_integer (®isters[REGISTER_BYTE (regno)],
+ REGISTER_RAW_SIZE (regno)));
+}
+
+LONGEST
+read_signed_register_pid (int regno, int pid)
+{
+ int save_pid;
+ LONGEST retval;
+
+ if (pid == inferior_pid)
+ return read_signed_register (regno);
+
+ save_pid = inferior_pid;
+
+ inferior_pid = pid;
+
+ retval = read_signed_register (regno);
+
+ inferior_pid = save_pid;
+
+ return retval;
+}
+
/* Store VALUE, into the raw contents of register number REGNO. */
void
&& memcmp (®isters[REGISTER_BYTE (regno)], buf, size) == 0)
return;
- target_prepare_to_store ();
+ if (regno < NUM_REGS)
+ target_prepare_to_store ();
memcpy (®isters[REGISTER_BYTE (regno)], buf, size);
register_valid[regno] = 1;
- target_store_registers (regno);
+ if (regno < NUM_REGS)
+ target_store_registers (regno);
+ else if (regno < NUM_REGS + NUM_PSEUDO_REGS)
+ STORE_PSEUDO_REGISTER (regno);
}
void
Ditto for write_pc.
1999-06-08: The following were re-written so that it assumes the
- existance of a TARGET_READ_PC et.al. macro. A default generic
+ existence of a TARGET_READ_PC et.al. macro. A default generic
version of that macro is made available where needed.
Since the ``TARGET_READ_PC'' et.al. macro is going to be controlled
eliminate the intermediate read_pc_pid(). The client would call
TARGET_READ_PC directly. (cagney). */
-#ifndef TARGET_READ_PC
-#define TARGET_READ_PC generic_target_read_pc
-#endif
-
CORE_ADDR
generic_target_read_pc (int pid)
{
return read_pc_pid (inferior_pid);
}
-#ifndef TARGET_WRITE_PC
-#define TARGET_WRITE_PC generic_target_write_pc
-#endif
-
void
generic_target_write_pc (CORE_ADDR pc, int pid)
{
/* Cope with strage ways of getting to the stack and frame pointers */
-#ifndef TARGET_READ_SP
-#define TARGET_READ_SP generic_target_read_sp
-#endif
-
CORE_ADDR
generic_target_read_sp (void)
{
return TARGET_READ_SP ();
}
-#ifndef TARGET_WRITE_SP
-#define TARGET_WRITE_SP generic_target_write_sp
-#endif
-
void
generic_target_write_sp (CORE_ADDR val)
{
TARGET_WRITE_SP (val);
}
-#ifndef TARGET_READ_FP
-#define TARGET_READ_FP generic_target_read_fp
-#endif
-
CORE_ADDR
generic_target_read_fp (void)
{
return TARGET_READ_FP ();
}
-#ifndef TARGET_WRITE_FP
-#define TARGET_WRITE_FP generic_target_write_fp
-#endif
-
void
generic_target_write_fp (CORE_ADDR val)
{
TARGET_WRITE_FP (val);
}
+/* ARGSUSED */
+static void
+reg_flush_command (char *command, int from_tty)
+{
+ /* Force-flush the register cache. */
+ registers_changed ();
+ if (from_tty)
+ 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 * sizeof (*register_valid);
+ 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);
register_gdbarch_swap (®isters, sizeof (registers), NULL);
register_gdbarch_swap (®ister_valid, sizeof (register_valid), NULL);
register_gdbarch_swap (NULL, 0, build_regcache);
+
+ add_com ("flushregs", class_maintenance, reg_flush_command,
+ "Force gdb to flush its register cache (maintainer command)");
}