* inferior.h (read_sp): Remove prototype.
[platform/upstream/binutils.git] / gdb / regcache.c
index d1067ea..bb9cfde 100644 (file)
@@ -1,7 +1,7 @@
 /* Cache and manage the values of registers for GDB, the GNU debugger.
 
-   Copyright 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.
 
@@ -17,8 +17,8 @@
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
+   Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
 
 #include "defs.h"
 #include "inferior.h"
@@ -51,7 +51,7 @@ struct regcache_descr
   /* The raw register cache.  Each raw (or hard) register is supplied
      by the target interface.  The raw cache should not contain
      redundant information - if the PC is constructed from two
-     registers then those regigisters and not the PC lives in the raw
+     registers then those registers and not the PC lives in the raw
      cache.  */
   int nr_raw_registers;
   long sizeof_raw_registers;
@@ -185,8 +185,12 @@ struct regcache
   /* The register buffers.  A read-only register cache can hold the
      full [0 .. NUM_REGS + NUM_PSEUDO_REGS) while a read/write
      register cache can only hold [0 .. NUM_REGS).  */
-  char *registers;
-  char *register_valid_p;
+  gdb_byte *registers;
+  /* 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
@@ -206,9 +210,9 @@ regcache_xmalloc (struct gdbarch *gdbarch)
   regcache = XMALLOC (struct regcache);
   regcache->descr = descr;
   regcache->registers
-    = XCALLOC (descr->sizeof_raw_registers, char);
+    = XCALLOC (descr->sizeof_raw_registers, gdb_byte);
   regcache->register_valid_p
-    = XCALLOC (descr->sizeof_raw_register_valid_p, char);
+    = XCALLOC (descr->sizeof_raw_register_valid_p, gdb_byte);
   regcache->readonly_p = 1;
   return regcache;
 }
@@ -245,7 +249,7 @@ get_regcache_arch (const struct regcache *regcache)
 
 /* Return  a pointer to register REGNUM's buffer cache.  */
 
-static char *
+static gdb_byte *
 register_buffer (const struct regcache *regcache, int regnum)
 {
   return regcache->registers + regcache->descr->register_offset[regnum];
@@ -256,7 +260,7 @@ regcache_save (struct regcache *dst, regcache_cooked_read_ftype *cooked_read,
               void *src)
 {
   struct gdbarch *gdbarch = dst->descr->gdbarch;
-  char buf[MAX_REGISTER_SIZE];
+  gdb_byte buf[MAX_REGISTER_SIZE];
   int regnum;
   /* The DST should be `read-only', if it wasn't then the save would
      end up trying to write the register values back out to the
@@ -287,10 +291,10 @@ regcache_save (struct regcache *dst, regcache_cooked_read_ftype *cooked_read,
 void
 regcache_restore (struct regcache *dst,
                  regcache_cooked_read_ftype *cooked_read,
-                 void *src)
+                 void *cooked_read_context)
 {
   struct gdbarch *gdbarch = dst->descr->gdbarch;
-  char buf[MAX_REGISTER_SIZE];
+  gdb_byte buf[MAX_REGISTER_SIZE];
   int regnum;
   /* The dst had better not be read-only.  If it is, the `restore'
      doesn't make much sense.  */
@@ -303,7 +307,7 @@ regcache_restore (struct regcache *dst,
     {
       if (gdbarch_register_reggroup_p (gdbarch, regnum, restore_reggroup))
        {
-         int valid = cooked_read (src, regnum, buf);
+         int valid = cooked_read (cooked_read_context, regnum, buf);
          if (valid)
            regcache_cooked_write (dst, regnum, buf);
        }
@@ -311,7 +315,7 @@ regcache_restore (struct regcache *dst,
 }
 
 static int
-do_cooked_read (void *src, int regnum, void *buf)
+do_cooked_read (void *src, int regnum, gdb_byte *buf)
 {
   struct regcache *regcache = src;
   if (!regcache->register_valid_p[regnum] && regcache->readonly_p)
@@ -328,7 +332,7 @@ void
 regcache_cpy (struct regcache *dst, struct regcache *src)
 {
   int i;
-  char *buf;
+  gdb_byte *buf;
   gdb_assert (src != NULL && dst != NULL);
   gdb_assert (src->descr->gdbarch == dst->descr->gdbarch);
   gdb_assert (src != dst);
@@ -377,19 +381,29 @@ regcache_dup_no_passthrough (struct regcache *src)
 }
 
 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];
 }
 
-char *
-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.  */
@@ -404,33 +418,6 @@ struct regcache *current_regcache;
 
 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
@@ -465,112 +452,12 @@ registers_changed (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, char *in_buf, int in_len)
-{
-  int in_end = in_start + in_len;
-  int regnum;
-  char 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, void *buf)
+regcache_raw_read (struct regcache *regcache, int regnum, gdb_byte *buf)
 {
   gdb_assert (regcache != NULL && buf != NULL);
   gdb_assert (regnum >= 0 && regnum < regcache->descr->nr_raw_registers);
@@ -586,8 +473,8 @@ regcache_raw_read (struct regcache *regcache, int regnum, void *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
@@ -595,7 +482,7 @@ regcache_raw_read (struct regcache *regcache, int regnum, void *buf)
         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.  */
@@ -606,7 +493,7 @@ regcache_raw_read (struct regcache *regcache, int regnum, void *buf)
 void
 regcache_raw_read_signed (struct regcache *regcache, int regnum, LONGEST *val)
 {
-  char *buf;
+  gdb_byte *buf;
   gdb_assert (regcache != NULL);
   gdb_assert (regnum >= 0 && regnum < regcache->descr->nr_raw_registers);
   buf = alloca (regcache->descr->sizeof_register[regnum]);
@@ -619,7 +506,7 @@ void
 regcache_raw_read_unsigned (struct regcache *regcache, int regnum,
                            ULONGEST *val)
 {
-  char *buf;
+  gdb_byte *buf;
   gdb_assert (regcache != NULL);
   gdb_assert (regnum >= 0 && regnum < regcache->descr->nr_raw_registers);
   buf = alloca (regcache->descr->sizeof_register[regnum]);
@@ -652,15 +539,7 @@ regcache_raw_write_unsigned (struct regcache *regcache, int regnum,
 }
 
 void
-deprecated_read_register_gen (int regnum, char *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, void *buf)
+regcache_cooked_read (struct regcache *regcache, int regnum, gdb_byte *buf)
 {
   gdb_assert (regnum >= 0);
   gdb_assert (regnum < regcache->descr->nr_cooked_registers);
@@ -681,7 +560,7 @@ void
 regcache_cooked_read_signed (struct regcache *regcache, int regnum,
                             LONGEST *val)
 {
-  char *buf;
+  gdb_byte *buf;
   gdb_assert (regcache != NULL);
   gdb_assert (regnum >= 0 && regnum < regcache->descr->nr_cooked_registers);
   buf = alloca (regcache->descr->sizeof_register[regnum]);
@@ -694,7 +573,7 @@ void
 regcache_cooked_read_unsigned (struct regcache *regcache, int regnum,
                               ULONGEST *val)
 {
-  char *buf;
+  gdb_byte *buf;
   gdb_assert (regcache != NULL);
   gdb_assert (regnum >= 0 && regnum < regcache->descr->nr_cooked_registers);
   buf = alloca (regcache->descr->sizeof_register[regnum]);
@@ -728,7 +607,8 @@ regcache_cooked_write_unsigned (struct regcache *regcache, int regnum,
 }
 
 void
-regcache_raw_write (struct regcache *regcache, int regnum, const void *buf)
+regcache_raw_write (struct regcache *regcache, int regnum,
+                   const gdb_byte *buf)
 {
   gdb_assert (regcache != NULL && buf != NULL);
   gdb_assert (regnum >= 0 && regnum < regcache->descr->nr_raw_registers);
@@ -754,23 +634,16 @@ regcache_raw_write (struct regcache *regcache, int regnum, const void *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);
+  target_store_registers (regcache, regnum);
 }
 
 void
-deprecated_write_register_gen (int regnum, char *buf)
-{
-  gdb_assert (current_regcache != NULL);
-  gdb_assert (current_regcache->descr->gdbarch == current_gdbarch);
-  regcache_cooked_write (current_regcache, regnum, buf);
-}
-
-void
-regcache_cooked_write (struct regcache *regcache, int regnum, const void *buf)
+regcache_cooked_write (struct regcache *regcache, int regnum,
+                      const gdb_byte *buf)
 {
   gdb_assert (regnum >= 0);
   gdb_assert (regnum < regcache->descr->nr_cooked_registers);
@@ -781,55 +654,6 @@ regcache_cooked_write (struct regcache *regcache, int regnum, const void *buf)
                                   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, char *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
-       {
-         char 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.  */
 
@@ -841,10 +665,13 @@ typedef void (regcache_write_ftype) (struct regcache *regcache, int regnum,
 static void
 regcache_xfer_part (struct regcache *regcache, int regnum,
                    int offset, int len, void *in, const void *out,
-                   regcache_read_ftype *read, regcache_write_ftype *write)
+                   void (*read) (struct regcache *regcache, int regnum,
+                                 gdb_byte *buf),
+                   void (*write) (struct regcache *regcache, int regnum,
+                                  const gdb_byte *buf))
 {
   struct regcache_descr *descr = regcache->descr;
-  bfd_byte reg[MAX_REGISTER_SIZE];
+  gdb_byte reg[MAX_REGISTER_SIZE];
   gdb_assert (offset >= 0 && offset <= descr->sizeof_register[regnum]);
   gdb_assert (len >= 0 && offset + len <= descr->sizeof_register[regnum]);
   /* Something to do?  */
@@ -873,7 +700,7 @@ regcache_xfer_part (struct regcache *regcache, int regnum,
 
 void
 regcache_raw_read_part (struct regcache *regcache, int regnum,
-                       int offset, int len, void *buf)
+                       int offset, int len, gdb_byte *buf)
 {
   struct regcache_descr *descr = regcache->descr;
   gdb_assert (regnum >= 0 && regnum < descr->nr_raw_registers);
@@ -883,7 +710,7 @@ regcache_raw_read_part (struct regcache *regcache, int regnum,
 
 void
 regcache_raw_write_part (struct regcache *regcache, int regnum,
-                        int offset, int len, const void *buf)
+                        int offset, int len, const gdb_byte *buf)
 {
   struct regcache_descr *descr = regcache->descr;
   gdb_assert (regnum >= 0 && regnum < descr->nr_raw_registers);
@@ -893,7 +720,7 @@ regcache_raw_write_part (struct regcache *regcache, int regnum,
 
 void
 regcache_cooked_read_part (struct regcache *regcache, int regnum,
-                          int offset, int len, void *buf)
+                          int offset, int len, gdb_byte *buf)
 {
   struct regcache_descr *descr = regcache->descr;
   gdb_assert (regnum >= 0 && regnum < descr->nr_cooked_registers);
@@ -903,7 +730,7 @@ regcache_cooked_read_part (struct regcache *regcache, int regnum,
 
 void
 regcache_cooked_write_part (struct regcache *regcache, int regnum,
-                           int offset, int len, const void *buf)
+                           int offset, int len, const gdb_byte *buf)
 {
   struct regcache_descr *descr = regcache->descr;
   gdb_assert (regnum >= 0 && regnum < descr->nr_cooked_registers);
@@ -922,21 +749,15 @@ register_offset_hack (struct gdbarch *gdbarch, int regnum)
   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)
 {
-  char *buf = alloca (register_size (current_gdbarch, regnum));
-  deprecated_read_register_gen (regnum, buf);
+  gdb_byte *buf = alloca (register_size (current_gdbarch, regnum));
+  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)));
 }
 
@@ -971,7 +792,9 @@ write_register (int regnum, LONGEST val)
   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
@@ -1044,8 +867,7 @@ regcache_raw_collect (const struct regcache *regcache, int regnum, void *buf)
 }
 
 
-/* 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.
@@ -1118,21 +940,6 @@ write_pc (CORE_ADDR pc)
   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)
@@ -1242,7 +1049,6 @@ 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 != DEPRECATED_REGISTER_BYTE (regnum)
              || (regnum > 0
                  && (regcache->descr->register_offset[regnum]
                      != (regcache->descr->register_offset[regnum - 1]