/* Cache and manage the values of registers for GDB, the GNU debugger.
- Copyright (C) 1986, 1987, 1989, 1991, 1994, 1995, 1996, 1998, 2000,
- 2001, 2002, 2004 Free Software Foundation, Inc.
+ Copyright (C) 1986, 1987, 1989, 1991, 1994, 1995, 1996, 1998, 2000, 2001,
+ 2002, 2004, 2007 Free Software Foundation, Inc.
This file is part of GDB.
full [0 .. NUM_REGS + NUM_PSEUDO_REGS) while a read/write
register cache can only hold [0 .. NUM_REGS). */
gdb_byte *registers;
- gdb_byte *register_valid_p;
+ /* Register cache status:
+ register_valid_p[REG] == 0 if REG value is not in the cache
+ > 0 if REG value is in the cache
+ < 0 if REG value is permanently unavailable */
+ signed char *register_valid_p;
/* Is this a read-only cache? A read-only cache is used for saving
the target's register state (e.g, across an inferior function
call or just before forcing a function return). A read-only
}
int
-regcache_valid_p (struct regcache *regcache, int regnum)
+regcache_valid_p (const struct regcache *regcache, int regnum)
{
gdb_assert (regcache != NULL);
- gdb_assert (regnum >= 0 && regnum < regcache->descr->nr_raw_registers);
+ gdb_assert (regnum >= 0);
+ if (regcache->readonly_p)
+ gdb_assert (regnum < regcache->descr->nr_cooked_registers);
+ else
+ gdb_assert (regnum < regcache->descr->nr_raw_registers);
+
return regcache->register_valid_p[regnum];
}
-gdb_byte *
-deprecated_grub_regcache_for_registers (struct regcache *regcache)
+void
+regcache_invalidate (struct regcache *regcache, int regnum)
{
- return regcache->registers;
+ gdb_assert (regcache != NULL);
+ gdb_assert (regnum >= 0);
+ gdb_assert (!regcache->readonly_p);
+ gdb_assert (regnum < regcache->descr->nr_raw_registers);
+ regcache->register_valid_p[regnum] = 0;
}
+
/* Global structure containing the current regcache. */
/* FIXME: cagney/2002-05-11: The two global arrays registers[] and
deprecated_register_valid[] currently point into this structure. */
static ptid_t registers_ptid;
-/*
- * FUNCTIONS:
- */
-
-/* REGISTER_CACHED()
-
- Returns 0 if the value is not in the cache (needs fetch).
- >0 if the value is in the cache.
- <0 if the value is permanently unavailable (don't ask again). */
-
-int
-register_cached (int regnum)
-{
- return current_regcache->register_valid_p[regnum];
-}
-
-/* Record that REGNUM's value is cached if STATE is >0, uncached but
- fetchable if STATE is 0, and uncached and unfetchable if STATE is <0. */
-
-void
-set_register_cached (int regnum, int state)
-{
- gdb_assert (regnum >= 0);
- gdb_assert (regnum < current_regcache->descr->nr_raw_registers);
- current_regcache->register_valid_p[regnum] = state;
-}
-
/* Observer for the target_changed event. */
void
alloca (0);
for (i = 0; i < current_regcache->descr->nr_raw_registers; i++)
- set_register_cached (i, 0);
-
- if (deprecated_registers_changed_hook)
- deprecated_registers_changed_hook ();
+ regcache_invalidate (current_regcache, i);
}
-/* DEPRECATED_REGISTERS_FETCHED ()
-
- Indicate that all registers have been fetched, so mark them all valid. */
-
-/* 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 regcache_raw_supply() the need for
- this function/hack is eliminated. */
-
-void
-deprecated_registers_fetched (void)
-{
- int i;
-
- 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. */
-}
-
-/* deprecated_read_register_bytes and deprecated_write_register_bytes
- are generally a *BAD* idea. They are inefficient because they need
- to check for partial updates, which can only be done by scanning
- through all of the registers and seeing if the bytes that are being
- read/written fall inside of an invalid register. [The main reason
- this is necessary is that register sizes can vary, so a simple
- index won't suffice.] It is far better to call read_register_gen
- and write_register_gen if you want to get at the raw register
- contents, as it only takes a regnum as an argument, and therefore
- can't do a partial register update.
-
- Prior to the recent fixes to check for partial updates, both read
- and deprecated_write_register_bytes always checked to see if any
- registers were stale, and then called target_fetch_registers (-1)
- to update the whole set. This caused really slowed things down for
- remote targets. */
-
-/* Copy INLEN bytes of consecutive data from registers
- starting with the INREGBYTE'th byte of register data
- into memory at MYADDR. */
-
-void
-deprecated_read_register_bytes (int in_start, gdb_byte *in_buf, int in_len)
-{
- int in_end = in_start + in_len;
- int regnum;
- gdb_byte reg_buf[MAX_REGISTER_SIZE];
-
- /* See if we are trying to read bytes from out-of-date registers. If so,
- update just those registers. */
-
- for (regnum = 0; regnum < NUM_REGS + NUM_PSEUDO_REGS; regnum++)
- {
- int reg_start;
- int reg_end;
- int reg_len;
- int start;
- int end;
- int byte;
-
- reg_start = DEPRECATED_REGISTER_BYTE (regnum);
- reg_len = register_size (current_gdbarch, regnum);
- reg_end = reg_start + reg_len;
-
- if (reg_end <= in_start || in_end <= reg_start)
- /* The range the user wants to read doesn't overlap with regnum. */
- continue;
-
- if (REGISTER_NAME (regnum) != NULL && *REGISTER_NAME (regnum) != '\0')
- /* Force the cache to fetch the entire register. */
- deprecated_read_register_gen (regnum, reg_buf);
-
- /* Legacy note: This function, for some reason, allows a NULL
- input buffer. If the buffer is NULL, the registers are still
- fetched, just the final transfer is skipped. */
- if (in_buf == NULL)
- continue;
-
- /* start = max (reg_start, in_start) */
- if (reg_start > in_start)
- start = reg_start;
- else
- start = in_start;
-
- /* end = min (reg_end, in_end) */
- if (reg_end < in_end)
- end = reg_end;
- else
- end = in_end;
-
- /* Transfer just the bytes common to both IN_BUF and REG_BUF */
- for (byte = start; byte < end; byte++)
- {
- in_buf[byte - in_start] = reg_buf[byte - reg_start];
- }
- }
-}
void
regcache_raw_read (struct regcache *regcache, int regnum, gdb_byte *buf)
registers_changed ();
registers_ptid = inferior_ptid;
}
- if (!register_cached (regnum))
- target_fetch_registers (regnum);
+ if (!regcache_valid_p (regcache, regnum))
+ target_fetch_registers (regcache, regnum);
#if 0
/* FIXME: cagney/2004-08-07: At present a number of targets
forget (or didn't know that they needed) to set this leading to
that a register is in one of the possible states: valid,
undefined, unknown. The last of which isn't yet
possible. */
- gdb_assert (register_cached (regnum));
+ gdb_assert (regcache_valid_p (regcache, regnum));
#endif
}
/* Copy the value directly into the register cache. */
regcache_raw_write (regcache, regnum, buf);
}
-void
-deprecated_read_register_gen (int regnum, gdb_byte *buf)
-{
- gdb_assert (current_regcache != NULL);
- gdb_assert (current_regcache->descr->gdbarch == current_gdbarch);
- regcache_cooked_read (current_regcache, regnum, buf);
-}
-
void
regcache_cooked_read (struct regcache *regcache, int regnum, gdb_byte *buf)
{
regcache->descr->sizeof_register[regnum]) == 0))
return;
- target_prepare_to_store ();
+ target_prepare_to_store (regcache);
memcpy (register_buffer (regcache, regnum), buf,
regcache->descr->sizeof_register[regnum]);
regcache->register_valid_p[regnum] = 1;
- target_store_registers (regnum);
-}
-
-void
-deprecated_write_register_gen (int regnum, gdb_byte *buf)
-{
- gdb_assert (current_regcache != NULL);
- gdb_assert (current_regcache->descr->gdbarch == current_gdbarch);
- regcache_cooked_write (current_regcache, regnum, buf);
+ target_store_registers (regcache, regnum);
}
void
regnum, buf);
}
-/* Copy INLEN bytes of consecutive data from memory at MYADDR
- into registers starting with the MYREGSTART'th byte of register data. */
-
-void
-deprecated_write_register_bytes (int myregstart, gdb_byte *myaddr, int inlen)
-{
- int myregend = myregstart + inlen;
- int regnum;
-
- target_prepare_to_store ();
-
- /* Scan through the registers updating any that are covered by the
- range myregstart<=>myregend using write_register_gen, which does
- nice things like handling threads, and avoiding updates when the
- new and old contents are the same. */
-
- for (regnum = 0; regnum < NUM_REGS + NUM_PSEUDO_REGS; regnum++)
- {
- int regstart, regend;
-
- regstart = DEPRECATED_REGISTER_BYTE (regnum);
- regend = regstart + register_size (current_gdbarch, regnum);
-
- /* Is this register completely outside the range the user is writing? */
- if (myregend <= regstart || regend <= myregstart)
- /* do nothing */ ;
-
- /* Is this register completely within the range the user is writing? */
- else if (myregstart <= regstart && regend <= myregend)
- deprecated_write_register_gen (regnum, myaddr + (regstart - myregstart));
-
- /* The register partially overlaps the range being written. */
- else
- {
- gdb_byte regbuf[MAX_REGISTER_SIZE];
- /* What's the overlap between this register's bytes and
- those the caller wants to write? */
- int overlapstart = max (regstart, myregstart);
- int overlapend = min (regend, myregend);
-
- /* We may be doing a partial update of an invalid register.
- Update it from the target before scribbling on it. */
- deprecated_read_register_gen (regnum, regbuf);
-
- target_store_registers (regnum);
- }
- }
-}
-
/* Perform a partial register transfer using a read, modify, write
operation. */
return descr->register_offset[regnum];
}
-/* Hack to keep code using register_bytes working. */
-
-int
-deprecated_register_bytes (void)
-{
- return current_regcache->descr->sizeof_raw_registers;
-}
-
/* Return the contents of register REGNUM as an unsigned integer. */
ULONGEST
read_register (int regnum)
{
gdb_byte *buf = alloca (register_size (current_gdbarch, regnum));
- deprecated_read_register_gen (regnum, buf);
+ gdb_assert (current_regcache != NULL);
+ gdb_assert (current_regcache->descr->gdbarch == current_gdbarch);
+ regcache_cooked_read (current_regcache, regnum, buf);
return (extract_unsigned_integer (buf, register_size (current_gdbarch, regnum)));
}
size = register_size (current_gdbarch, regnum);
buf = alloca (size);
store_signed_integer (buf, size, (LONGEST) val);
- deprecated_write_register_gen (regnum, buf);
+ gdb_assert (current_regcache != NULL);
+ gdb_assert (current_regcache->descr->gdbarch == current_gdbarch);
+ regcache_cooked_write (current_regcache, regnum, buf);
}
void
}
-/* read_pc, write_pc, read_sp, etc. Special handling for registers
- PC, SP, and FP. */
+/* read_pc, write_pc, etc. Special handling for register PC. */
/* NOTE: cagney/2001-02-18: The functions read_pc_pid(), read_pc() and
read_sp(), will eventually be replaced by per-frame methods.
write_pc_pid (pc, inferior_ptid);
}
-/* Cope with strage ways of getting to the stack and frame pointers */
-
-CORE_ADDR
-read_sp (void)
-{
- if (TARGET_READ_SP_P ())
- return TARGET_READ_SP ();
- else if (gdbarch_unwind_sp_p (current_gdbarch))
- return get_frame_sp (get_current_frame ());
- else if (SP_REGNUM >= 0)
- /* Try SP_REGNUM last: this makes all sorts of [wrong] assumptions
- about the architecture so put it at the end. */
- return read_register (SP_REGNUM);
- internal_error (__FILE__, __LINE__, _("read_sp: Unable to find SP"));
-}
static void
reg_flush_command (char *command, int from_tty)
fprintf_unfiltered (file, " %6ld",
regcache->descr->register_offset[regnum]);
if (register_offset != regcache->descr->register_offset[regnum]
- || register_offset != DEPRECATED_REGISTER_BYTE (regnum)
|| (regnum > 0
&& (regcache->descr->register_offset[regnum]
!= (regcache->descr->register_offset[regnum - 1]