This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[unavailable regs/locals, 01/11] registers status upwards


This is a step in the direction of glueing unavailable registers
to unavailable values.

Make the regcache_XXX_read_XXX functions return an indication
of whether the register's value is valid, so that the
frame module can mark frame registers as unavailable.

That's straight forward for raw registers.  For pseudo-registers,
which are built from raw registers (or something else),
only each target backend knows what from and how is a given pseudo-register
contructable.  So, change gdbarch_pseudo_register_read to
return a register status, indicating when a pseudo
register was being build from non valid raw registers
(or something else).  This then requires updating all
gdbarch target backends.  Most needed boring mechanical
changes, and couple required a bit more, but nothing fancy.

-- 
Pedro Alves

2011-02-22  Pedro Alves  <pedro@codesourcery.com>

	gdb/
	* regcache.h (regcache_raw_read, regcache_raw_read_signed)
	(regcache_raw_read_unsigned, regcache_raw_read_signed)
	(regcache_raw_read_unsigned, regcache_raw_read_part)
	(regcache_cooked_read, regcache_cooked_read_signed)
	(regcache_cooked_read_unsigned, regcache_cooked_read_part)
	(regcache_cooked_read_ftype): Change return to enum
	register_status.
	* regcache.c (regcache_save): Adjust to handle REG_UNAVAILABLE
	registers.
	(do_cooked_read): Change return to enum register_status.  Always
	forward to regcache_cooked_read.
	(regcache_raw_read): Change return to enum register_status.  If
	the register is not REG_VALID, memset the buffer.  Return the
	register's status.
	(regcache_raw_read_signed): Handle non-REG_VALID registers and
	return the register's status.
	(regcache_raw_read_unsigned): Ditto.
	(regcache_cooked_read): Change return to enum register_status.
	Assert that with read-only regcaches, the register's status must
	be known.  If the regcache is read-only, and the register is not
	REG_VALID, memset the buffer.  Return the register's status.
	(regcache_cooked_read_signed): Change return to enum
	register_status.  Handle non-REG_VALID registers and return the
	register's status.
	(regcache_cooked_read_unsigned): Change return to enum
	register_status.  Handle non-REG_VALID registers and return the
	register's status.
	(regcache_xfer_part, regcache_raw_read_part)
	(regcache_cooked_read_part): Change return to enum
	register_status.  Return the register's status.
	* frame.c (do_frame_register_read): Adjust interface to match
	regcache_cooked_read_ftype.
	* gdbarch.sh (pseudo_register_read): Change return to enum
	register_status.
	* gdbarch.h, gdbarch.c: Regenerate.

	* i386-tdep.h (i386_pseudo_register_read): Change return to enum
	register_status.
	* i386-tdep.c (i386_pseudo_register_read): Change return to enum
	register_status.  If reading a raw register indicates the raw
	register is not valid, return the raw register's status,
	otherwise, return REG_VALID.
	* amd64-tdep.c (amd64_pseudo_register_read): Change return to enum
	register_status.  Handle non-REG_VALID raw registers and return
	the register's status.
	* arm-tdep.c (arm_neon_quad_read)
	(arm_pseudo_read): Change return to enum register_status.  Handle
	non-REG_VALID raw registers and return the register's status.
	* avr-tdep.c (avr_pseudo_register_read): Ditto.
	* frv-tdep.c (frv_pseudo_register_read): Ditto.
	* h8300-tdep.c (h8300_pseudo_register_read): Ditto.
	* hppa-tdep.c (hppa_pseudo_register_read): Ditto.
	* m32c-tdep.c (m32c_move_reg_t): Change return to enum
	register_status.
	(m32c_raw_read, m32c_raw_write, m32c_banked_read)
	(m32c_banked_write, m32c_sb_read, m32c_sb_write, m32c_part_read)
	(m32c_part_write, m32c_cat_read, m32c_cat_write)
	(m32c_r3r2r1r0_read, m32c_r3r2r1r0_write)
	(m32c_pseudo_register_read): Change return to enum
	register_status.  Adjust.
	* m68hc11-tdep.c (m68hc11_pseudo_register_read): Change return to
	enum register_status.  Return the register's status.
	* mep-tdep.c (mep_pseudo_cr32_read): Change return to enum
	register_status.  Return the register's status.
	(mep_pseudo_cr64_read, mep_pseudo_register_read): Ditto.
	* mips-tdep.c (mips_pseudo_register_read): Ditto.
	* mt-tdep.c (mt_pseudo_register_read): Ditto.
	* rs6000-tdep.c (move_ev_register_func): New typedef.
	(e500_move_ev_register): Use it.  Change return to enum
	register_status.  Return the register's status.
	(do_regcache_raw_read): New function.
	(do_regcache_raw_write): New function.
	(e500_pseudo_register_read): Change return to enum
	register_status.  Return the register's status.  Use
	do_regcache_raw_read.
	(e500_pseudo_register_write): Adjust.  Use do_regcache_raw_write.
	(dfp_pseudo_register_read): Change return to enum register_status.
	Return the register's status.
	(vsx_pseudo_register_read): Ditto.
	(efpr_pseudo_register_read): Ditto.
	(rs6000_pseudo_register_read): Ditto.
	* s390-tdep.c (s390_pseudo_register_read): Change return to enum
	register_status.  Return the register's status.
	* sh64-tdep.c (pseudo_register_read_portions): New function.
	(sh64_pseudo_register_read): Change return to enum
	register_status.  Use pseudo_register_read_portions.  Return the
	register's status.
	* ia64-tdep.c (ia64_pseudo_register_read): Change return to enum
	register_status.  Return the register's status.
	* sh-tdep.c (pseudo_register_read_portions): New function.
	(sh_pseudo_register_read): Change return to enum register_status.
	Use pseudo_register_read_portions.  Return the register's status.
	* sparc-tdep.c (sparc32_pseudo_register_read): Change return to
	enum register_status.  Return the register's status.
	* sparc64-tdep.c (sparc64_pseudo_register_read): Ditto.
	* spu-tdep.c (spu_pseudo_register_read_spu)
	(spu_pseudo_register_read): Ditto.
	* xtensa-tdep.c (xtensa_register_read_masked)
	(xtensa_pseudo_register_read): Ditto.
	* bfin-tdep.c (bfin_pseudo_register_read): Ditto.
	(bfin_pseudo_register_write): Adjust.

---
 gdb/amd64-tdep.c   |   27 ++++++---
 gdb/arm-tdep.c     |   31 +++++++---
 gdb/avr-tdep.c     |    9 ++-
 gdb/bfin-tdep.c    |   23 +++++--
 gdb/frame.c        |    7 +-
 gdb/frv-tdep.c     |   29 ++++++----
 gdb/gdbarch.c      |    4 -
 gdb/gdbarch.h      |    4 -
 gdb/gdbarch.sh     |    2 
 gdb/h8300-tdep.c   |    8 +-
 gdb/hppa-tdep.c    |   19 ++++--
 gdb/i386-tdep.c    |   33 +++++++----
 gdb/i386-tdep.h    |    7 +-
 gdb/ia64-tdep.c    |   51 +++++++++++++----
 gdb/m32c-tdep.c    |   96 +++++++++++++++++++++------------
 gdb/m68hc11-tdep.c |   11 ++-
 gdb/mep-tdep.c     |   27 +++++----
 gdb/mips-tdep.c    |   14 +++-
 gdb/mt-tdep.c      |   29 ++++++----
 gdb/regcache.c     |  153 +++++++++++++++++++++++++++++++++--------------------
 gdb/regcache.h     |   66 ++++++++++++----------
 gdb/rs6000-tdep.c  |  119 ++++++++++++++++++++++++++---------------
 gdb/s390-tdep.c    |   54 ++++++++++++------
 gdb/sh-tdep.c      |   63 +++++++++++++++------
 gdb/sh64-tdep.c    |  108 ++++++++++++++++++++++++-------------
 gdb/sparc-tdep.c   |   10 ++-
 gdb/sparc64-tdep.c |   41 ++++++++++----
 gdb/spu-tdep.c     |   35 ++++++------
 gdb/xtensa-tdep.c  |   36 +++++++-----
 29 files changed, 725 insertions(+), 391 deletions(-)

Index: src/gdb/regcache.h
===================================================================
--- src.orig/gdb/regcache.h	2011-02-21 20:30:32.149344005 +0000
+++ src/gdb/regcache.h	2011-02-22 11:38:56.344708016 +0000
@@ -64,49 +64,53 @@ enum register_status regcache_register_s
 					       int regnum);
 
 /* Transfer a raw register [0..NUM_REGS) between core-gdb and the
-   regcache.  */
+   regcache.  The read variants return the status of the register.  */
 
-void regcache_raw_read (struct regcache *regcache, int rawnum, gdb_byte *buf);
+enum register_status regcache_raw_read (struct regcache *regcache,
+					int rawnum, gdb_byte *buf);
 void regcache_raw_write (struct regcache *regcache, int rawnum,
 			 const gdb_byte *buf);
-extern void regcache_raw_read_signed (struct regcache *regcache,
-				      int regnum, LONGEST *val);
-extern void regcache_raw_read_unsigned (struct regcache *regcache,
-					int regnum, ULONGEST *val);
+extern enum register_status
+  regcache_raw_read_signed (struct regcache *regcache,
+			    int regnum, LONGEST *val);
+extern enum register_status
+  regcache_raw_read_unsigned (struct regcache *regcache,
+			      int regnum, ULONGEST *val);
 extern void regcache_raw_write_signed (struct regcache *regcache,
 				       int regnum, LONGEST val);
 extern void regcache_raw_write_unsigned (struct regcache *regcache,
 					 int regnum, ULONGEST val);
 
-/* Partial transfer of a raw registers.  These perform read, modify,
-   write style operations.  */
-
-void regcache_raw_read_part (struct regcache *regcache, int regnum,
-			     int offset, int len, gdb_byte *buf);
+/* Partial transfer of raw registers.  These perform read, modify,
+   write style operations.  The read variant returns the status of the
+   register.  */
+
+extern enum register_status
+  regcache_raw_read_part (struct regcache *regcache, int regnum,
+			  int offset, int len, gdb_byte *buf);
 void regcache_raw_write_part (struct regcache *regcache, int regnum,
 			      int offset, int len, const gdb_byte *buf);
 
 void regcache_invalidate (struct regcache *regcache, int regnum);
 
+/* Transfer of pseudo-registers.  The read variants return a register
+   status, as an indication of when a ``cooked'' register was
+   constructed from valid, invalid or unavailable ``raw''
+   registers.  */
+
 /* Transfer a cooked register [0..NUM_REGS+NUM_PSEUDO_REGS).  */
-void regcache_cooked_read (struct regcache *regcache, int rawnum,
-			   gdb_byte *buf);
+enum register_status regcache_cooked_read (struct regcache *regcache,
+					   int rawnum, gdb_byte *buf);
 void regcache_cooked_write (struct regcache *regcache, int rawnum,
 			    const gdb_byte *buf);
-
-/* NOTE: cagney/2002-08-13: At present GDB has no reliable mechanism
-   for indicating when a ``cooked'' register was constructed from
-   invalid or unavailable ``raw'' registers.  One fairly easy way of
-   adding such a mechanism would be for the cooked functions to return
-   a register valid indication.  Given the possibility of such a
-   change, the extract functions below use a reference parameter,
-   rather than a function result.  */
-
+
 /* Read a register as a signed/unsigned quantity.  */
-extern void regcache_cooked_read_signed (struct regcache *regcache,
-					 int regnum, LONGEST *val);
-extern void regcache_cooked_read_unsigned (struct regcache *regcache,
-					   int regnum, ULONGEST *val);
+extern enum register_status
+  regcache_cooked_read_signed (struct regcache *regcache,
+			       int regnum, LONGEST *val);
+extern enum register_status
+  regcache_cooked_read_unsigned (struct regcache *regcache,
+				 int regnum, ULONGEST *val);
 extern void regcache_cooked_write_signed (struct regcache *regcache,
 					  int regnum, LONGEST val);
 extern void regcache_cooked_write_unsigned (struct regcache *regcache,
@@ -115,8 +119,9 @@ extern void regcache_cooked_write_unsign
 /* Partial transfer of a cooked register.  These perform read, modify,
    write style operations.  */
 
-void regcache_cooked_read_part (struct regcache *regcache, int regnum,
-				int offset, int len, gdb_byte *buf);
+enum register_status regcache_cooked_read_part (struct regcache *regcache,
+						int regnum, int offset,
+						int len, gdb_byte *buf);
 void regcache_cooked_write_part (struct regcache *regcache, int regnum,
 				 int offset, int len, const gdb_byte *buf);
 
@@ -153,8 +158,9 @@ extern int register_size (struct gdbarch
    restore_reggroup respectively.  COOKED_READ returns zero iff the
    register's value can't be returned.  */
 
-typedef int (regcache_cooked_read_ftype) (void *src, int regnum,
-					  gdb_byte *buf);
+typedef enum register_status (regcache_cooked_read_ftype) (void *src,
+							   int regnum,
+							   gdb_byte *buf);
 
 extern void regcache_save (struct regcache *dst,
 			   regcache_cooked_read_ftype *cooked_read,
Index: src/gdb/regcache.c
===================================================================
--- src.orig/gdb/regcache.c	2011-02-21 20:30:32.149344005 +0000
+++ src/gdb/regcache.c	2011-02-21 21:09:45.449344005 +0000
@@ -312,14 +312,19 @@ regcache_save (struct regcache *dst, reg
     {
       if (gdbarch_register_reggroup_p (gdbarch, regnum, save_reggroup))
 	{
-	  int valid = cooked_read (src, regnum, buf);
+	  enum register_status status = cooked_read (src, regnum, buf);
 
-	  if (valid)
+	  if (status == REG_VALID)
+	    memcpy (register_buffer (dst, regnum), buf,
+		    register_size (gdbarch, regnum));
+	  else
 	    {
-	      memcpy (register_buffer (dst, regnum), buf,
+	      gdb_assert (status != REG_UNKNOWN);
+
+	      memset (register_buffer (dst, regnum), 0,
 		      register_size (gdbarch, regnum));
-	      dst->register_status[regnum] = REG_VALID;
 	    }
+	  dst->register_status[regnum] = status;
 	}
     }
 }
@@ -352,21 +357,14 @@ regcache_restore (struct regcache *dst,
     }
 }
 
-static int
+static enum register_status
 do_cooked_read (void *src, int regnum, gdb_byte *buf)
 {
   struct regcache *regcache = src;
 
-  if (regcache->register_status[regnum] == REG_UNKNOWN && regcache->readonly_p)
-    /* Don't even think about fetching a register from a read-only
-       cache when the register isn't yet valid.  There isn't a target
-       from which the register value can be fetched.  */
-    return 0;
-  regcache_cooked_read (regcache, regnum, buf);
-  return 1;
+  return regcache_cooked_read (regcache, regnum, buf);
 }
 
-
 void
 regcache_cpy (struct regcache *dst, struct regcache *src)
 {
@@ -578,7 +576,7 @@ registers_changed (void)
   alloca (0);
 }
 
-void
+enum register_status
 regcache_raw_read (struct regcache *regcache, int regnum, gdb_byte *buf)
 {
   gdb_assert (regcache != NULL && buf != NULL);
@@ -607,38 +605,53 @@ regcache_raw_read (struct regcache *regc
       gdb_assert (regcache_register_status (regcache, regnum) == REG_VALID);
 #endif
     }
-  /* Copy the value directly into the register cache.  */
-  memcpy (buf, register_buffer (regcache, regnum),
-	  regcache->descr->sizeof_register[regnum]);
+
+  if (regcache->register_status[regnum] != REG_VALID)
+    memset (buf, 0, regcache->descr->sizeof_register[regnum]);
+  else
+    memcpy (buf, register_buffer (regcache, regnum),
+	    regcache->descr->sizeof_register[regnum]);
+
+  return regcache->register_status[regnum];
 }
 
-void
+enum register_status
 regcache_raw_read_signed (struct regcache *regcache, int regnum, LONGEST *val)
 {
   gdb_byte *buf;
+  enum register_status status;
 
   gdb_assert (regcache != NULL);
   gdb_assert (regnum >= 0 && regnum < regcache->descr->nr_raw_registers);
   buf = alloca (regcache->descr->sizeof_register[regnum]);
-  regcache_raw_read (regcache, regnum, buf);
-  (*val) = extract_signed_integer
-	     (buf, regcache->descr->sizeof_register[regnum],
-	      gdbarch_byte_order (regcache->descr->gdbarch));
+  status = regcache_raw_read (regcache, regnum, buf);
+  if (status == REG_VALID)
+    *val = extract_signed_integer
+      (buf, regcache->descr->sizeof_register[regnum],
+       gdbarch_byte_order (regcache->descr->gdbarch));
+  else
+    *val = 0;
+  return status;
 }
 
-void
+enum register_status
 regcache_raw_read_unsigned (struct regcache *regcache, int regnum,
 			    ULONGEST *val)
 {
   gdb_byte *buf;
+  enum register_status status;
 
   gdb_assert (regcache != NULL);
   gdb_assert (regnum >= 0 && regnum < regcache->descr->nr_raw_registers);
   buf = alloca (regcache->descr->sizeof_register[regnum]);
-  regcache_raw_read (regcache, regnum, buf);
-  (*val) = extract_unsigned_integer
-	     (buf, regcache->descr->sizeof_register[regnum],
-	      gdbarch_byte_order (regcache->descr->gdbarch));
+  status = regcache_raw_read (regcache, regnum, buf);
+  if (status == REG_VALID)
+    *val = extract_unsigned_integer
+      (buf, regcache->descr->sizeof_register[regnum],
+       gdbarch_byte_order (regcache->descr->gdbarch));
+  else
+    *val = 0;
+  return status;
 }
 
 void
@@ -668,52 +681,71 @@ regcache_raw_write_unsigned (struct regc
   regcache_raw_write (regcache, regnum, buf);
 }
 
-void
+enum register_status
 regcache_cooked_read (struct regcache *regcache, int regnum, gdb_byte *buf)
 {
   gdb_assert (regnum >= 0);
   gdb_assert (regnum < regcache->descr->nr_cooked_registers);
   if (regnum < regcache->descr->nr_raw_registers)
-    regcache_raw_read (regcache, regnum, buf);
+    return regcache_raw_read (regcache, regnum, buf);
   else if (regcache->readonly_p
-	   && regnum < regcache->descr->nr_cooked_registers
-	   && regcache->register_status[regnum] == REG_VALID)
-    /* Read-only register cache, and the cooked value was cached.  */
-    memcpy (buf, register_buffer (regcache, regnum),
-	    regcache->descr->sizeof_register[regnum]);
+	   && regcache->register_status[regnum] != REG_UNKNOWN)
+    {
+      /* Read-only register cache, perhaps the cooked value was
+	 cached?  */
+      struct gdbarch *gdbarch = regcache->descr->gdbarch;
+
+      if (regcache->register_status[regnum] == REG_VALID)
+	memcpy (buf, register_buffer (regcache, regnum),
+		regcache->descr->sizeof_register[regnum]);
+      else
+	memset (buf, 0, regcache->descr->sizeof_register[regnum]);
+
+      return regcache->register_status[regnum];
+    }
   else
-    gdbarch_pseudo_register_read (regcache->descr->gdbarch, regcache,
-				  regnum, buf);
+    return gdbarch_pseudo_register_read (regcache->descr->gdbarch, regcache,
+					 regnum, buf);
 }
 
-void
+enum register_status
 regcache_cooked_read_signed (struct regcache *regcache, int regnum,
 			     LONGEST *val)
 {
+  enum register_status status;
   gdb_byte *buf;
 
   gdb_assert (regcache != NULL);
   gdb_assert (regnum >= 0 && regnum < regcache->descr->nr_cooked_registers);
   buf = alloca (regcache->descr->sizeof_register[regnum]);
-  regcache_cooked_read (regcache, regnum, buf);
-  (*val) = extract_signed_integer
-	     (buf, regcache->descr->sizeof_register[regnum],
-	      gdbarch_byte_order (regcache->descr->gdbarch));
+  status = regcache_cooked_read (regcache, regnum, buf);
+  if (status == REG_VALID)
+    *val = extract_signed_integer
+      (buf, regcache->descr->sizeof_register[regnum],
+       gdbarch_byte_order (regcache->descr->gdbarch));
+  else
+    *val = 0;
+  return status;
 }
 
-void
+enum register_status
 regcache_cooked_read_unsigned (struct regcache *regcache, int regnum,
 			       ULONGEST *val)
 {
+  enum register_status status;
   gdb_byte *buf;
 
   gdb_assert (regcache != NULL);
   gdb_assert (regnum >= 0 && regnum < regcache->descr->nr_cooked_registers);
   buf = alloca (regcache->descr->sizeof_register[regnum]);
-  regcache_cooked_read (regcache, regnum, buf);
-  (*val) = extract_unsigned_integer
-	     (buf, regcache->descr->sizeof_register[regnum],
-	      gdbarch_byte_order (regcache->descr->gdbarch));
+  status = regcache_cooked_read (regcache, regnum, buf);
+  if (status == REG_VALID)
+    *val = extract_unsigned_integer
+      (buf, regcache->descr->sizeof_register[regnum],
+       gdbarch_byte_order (regcache->descr->gdbarch));
+  else
+    *val = 0;
+  return status;
 }
 
 void
@@ -799,11 +831,12 @@ typedef void (regcache_read_ftype) (stru
 typedef void (regcache_write_ftype) (struct regcache *regcache, int regnum,
 				     const void *buf);
 
-static void
+static enum register_status
 regcache_xfer_part (struct regcache *regcache, int regnum,
 		    int offset, int len, void *in, const void *out,
-		    void (*read) (struct regcache *regcache, int regnum,
-				  gdb_byte *buf),
+		    enum register_status (*read) (struct regcache *regcache,
+						  int regnum,
+						  gdb_byte *buf),
 		    void (*write) (struct regcache *regcache, int regnum,
 				   const gdb_byte *buf))
 {
@@ -814,14 +847,18 @@ regcache_xfer_part (struct regcache *reg
   gdb_assert (len >= 0 && offset + len <= descr->sizeof_register[regnum]);
   /* Something to do?  */
   if (offset + len == 0)
-    return;
+    return REG_VALID;
   /* Read (when needed) ...  */
   if (in != NULL
       || offset > 0
       || offset + len < descr->sizeof_register[regnum])
     {
+      enum register_status status;
+
       gdb_assert (read != NULL);
-      read (regcache, regnum, reg);
+      status = read (regcache, regnum, reg);
+      if (status != REG_VALID)
+	return status;
     }
   /* ... modify ...  */
   if (in != NULL)
@@ -834,17 +871,19 @@ regcache_xfer_part (struct regcache *reg
       gdb_assert (write != NULL);
       write (regcache, regnum, reg);
     }
+
+  return REG_VALID;
 }
 
-void
+enum register_status
 regcache_raw_read_part (struct regcache *regcache, int regnum,
 			int offset, int len, gdb_byte *buf)
 {
   struct regcache_descr *descr = regcache->descr;
 
   gdb_assert (regnum >= 0 && regnum < descr->nr_raw_registers);
-  regcache_xfer_part (regcache, regnum, offset, len, buf, NULL,
-		      regcache_raw_read, regcache_raw_write);
+  return regcache_xfer_part (regcache, regnum, offset, len, buf, NULL,
+			     regcache_raw_read, regcache_raw_write);
 }
 
 void
@@ -858,15 +897,15 @@ regcache_raw_write_part (struct regcache
 		      regcache_raw_read, regcache_raw_write);
 }
 
-void
+enum register_status
 regcache_cooked_read_part (struct regcache *regcache, int regnum,
 			   int offset, int len, gdb_byte *buf)
 {
   struct regcache_descr *descr = regcache->descr;
 
   gdb_assert (regnum >= 0 && regnum < descr->nr_cooked_registers);
-  regcache_xfer_part (regcache, regnum, offset, len, buf, NULL,
-		      regcache_cooked_read, regcache_cooked_write);
+  return regcache_xfer_part (regcache, regnum, offset, len, buf, NULL,
+			     regcache_cooked_read, regcache_cooked_write);
 }
 
 void
Index: src/gdb/frame.c
===================================================================
--- src.orig/gdb/frame.c	2011-02-21 20:30:32.149344005 +0000
+++ src/gdb/frame.c	2011-02-21 21:09:45.449344005 +0000
@@ -687,10 +687,13 @@ get_frame_func (struct frame_info *this_
   return next_frame->prev_func.addr;
 }
 
-static int
+static enum register_status
 do_frame_register_read (void *src, int regnum, gdb_byte *buf)
 {
-  return frame_register_read (src, regnum, buf);
+  if (!frame_register_read (src, regnum, buf))
+    return REG_UNAVAILABLE;
+  else
+    return REG_VALID;
 }
 
 struct regcache *
Index: src/gdb/gdbarch.sh
===================================================================
--- src.orig/gdb/gdbarch.sh	2011-02-21 20:30:32.149344005 +0000
+++ src/gdb/gdbarch.sh	2011-02-21 21:09:45.449344005 +0000
@@ -417,7 +417,7 @@ F:void:write_pc:struct regcache *regcach
 # serious shakedown.
 m:void:virtual_frame_pointer:CORE_ADDR pc, int *frame_regnum, LONGEST *frame_offset:pc, frame_regnum, frame_offset:0:legacy_virtual_frame_pointer::0
 #
-M:void:pseudo_register_read:struct regcache *regcache, int cookednum, gdb_byte *buf:regcache, cookednum, buf
+M:enum register_status:pseudo_register_read:struct regcache *regcache, int cookednum, gdb_byte *buf:regcache, cookednum, buf
 M:void:pseudo_register_write:struct regcache *regcache, int cookednum, const gdb_byte *buf:regcache, cookednum, buf
 #
 v:int:num_regs:::0:-1
Index: src/gdb/gdbarch.h
===================================================================
--- src.orig/gdb/gdbarch.h	2011-02-21 20:30:32.149344005 +0000
+++ src/gdb/gdbarch.h	2011-02-21 21:09:45.449344005 +0000
@@ -212,8 +212,8 @@ extern void set_gdbarch_virtual_frame_po
 
 extern int gdbarch_pseudo_register_read_p (struct gdbarch *gdbarch);
 
-typedef void (gdbarch_pseudo_register_read_ftype) (struct gdbarch *gdbarch, struct regcache *regcache, int cookednum, gdb_byte *buf);
-extern void gdbarch_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache, int cookednum, gdb_byte *buf);
+typedef enum register_status (gdbarch_pseudo_register_read_ftype) (struct gdbarch *gdbarch, struct regcache *regcache, int cookednum, gdb_byte *buf);
+extern enum register_status gdbarch_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache, int cookednum, gdb_byte *buf);
 extern void set_gdbarch_pseudo_register_read (struct gdbarch *gdbarch, gdbarch_pseudo_register_read_ftype *pseudo_register_read);
 
 extern int gdbarch_pseudo_register_write_p (struct gdbarch *gdbarch);
Index: src/gdb/gdbarch.c
===================================================================
--- src.orig/gdb/gdbarch.c	2011-02-21 20:30:32.149344005 +0000
+++ src/gdb/gdbarch.c	2011-02-21 21:09:45.459344006 +0000
@@ -1682,14 +1682,14 @@ gdbarch_pseudo_register_read_p (struct g
   return gdbarch->pseudo_register_read != NULL;
 }
 
-void
+enum register_status
 gdbarch_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache, int cookednum, gdb_byte *buf)
 {
   gdb_assert (gdbarch != NULL);
   gdb_assert (gdbarch->pseudo_register_read != NULL);
   if (gdbarch_debug >= 2)
     fprintf_unfiltered (gdb_stdlog, "gdbarch_pseudo_register_read called\n");
-  gdbarch->pseudo_register_read (gdbarch, regcache, cookednum, buf);
+  return gdbarch->pseudo_register_read (gdbarch, regcache, cookednum, buf);
 }
 
 void
Index: src/gdb/i386-tdep.h
===================================================================
--- src.orig/gdb/i386-tdep.h	2011-02-21 20:30:32.149344005 +0000
+++ src/gdb/i386-tdep.h	2011-02-21 21:09:45.459344006 +0000
@@ -311,9 +311,10 @@ extern int i386_ymm_regnum_p (struct gdb
 extern const char *i386_pseudo_register_name (struct gdbarch *gdbarch,
 					      int regnum);
 
-extern void i386_pseudo_register_read (struct gdbarch *gdbarch,
-				       struct regcache *regcache,
-				       int regnum, gdb_byte *buf);
+extern enum register_status i386_pseudo_register_read (struct gdbarch *gdbarch,
+						       struct regcache *regcache,
+						       int regnum,
+						       gdb_byte *buf);
 extern void i386_pseudo_register_write (struct gdbarch *gdbarch,
 					struct regcache *regcache,
 					int regnum, const gdb_byte *buf);
Index: src/gdb/i386-tdep.c
===================================================================
--- src.orig/gdb/i386-tdep.c	2011-02-21 20:30:32.149344005 +0000
+++ src/gdb/i386-tdep.c	2011-02-21 21:09:45.459344006 +0000
@@ -2510,18 +2510,21 @@ i386_mmx_regnum_to_fp_regnum (struct reg
   return (I387_ST0_REGNUM (tdep) + fpreg);
 }
 
-void
+enum register_status
 i386_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
 			   int regnum, gdb_byte *buf)
 {
   gdb_byte raw_buf[MAX_REGISTER_SIZE];
+  enum register_status status;
 
   if (i386_mmx_regnum_p (gdbarch, regnum))
     {
       int fpnum = i386_mmx_regnum_to_fp_regnum (regcache, regnum);
 
       /* Extract (always little endian).  */
-      regcache_raw_read (regcache, fpnum, raw_buf);
+      status = regcache_raw_read (regcache, fpnum, raw_buf);
+      if (status != REG_VALID)
+	return status;
       memcpy (buf, raw_buf, register_size (gdbarch, regnum));
     }
   else
@@ -2533,14 +2536,18 @@ i386_pseudo_register_read (struct gdbarc
 	  regnum -= tdep->ymm0_regnum;
 
 	  /* Extract (always little endian).  Read lower 128bits.  */
-	  regcache_raw_read (regcache,
-			     I387_XMM0_REGNUM (tdep) + regnum,
-			     raw_buf);
+	  status = regcache_raw_read (regcache,
+				      I387_XMM0_REGNUM (tdep) + regnum,
+				      raw_buf);
+	  if (status != REG_VALID)
+	    return status;
 	  memcpy (buf, raw_buf, 16);
 	  /* Read upper 128bits.  */
-	  regcache_raw_read (regcache,
-			     tdep->ymm0h_regnum + regnum,
-			     raw_buf);
+	  status = regcache_raw_read (regcache,
+				      tdep->ymm0h_regnum + regnum,
+				      raw_buf);
+	  if (status != REG_VALID)
+	    return status;
 	  memcpy (buf + 16, raw_buf, 16);
 	}
       else if (i386_word_regnum_p (gdbarch, regnum))
@@ -2548,7 +2555,9 @@ i386_pseudo_register_read (struct gdbarc
 	  int gpnum = regnum - tdep->ax_regnum;
 
 	  /* Extract (always little endian).  */
-	  regcache_raw_read (regcache, gpnum, raw_buf);
+	  status = regcache_raw_read (regcache, gpnum, raw_buf);
+	  if (status != REG_VALID)
+	    return status;
 	  memcpy (buf, raw_buf, 2);
 	}
       else if (i386_byte_regnum_p (gdbarch, regnum))
@@ -2560,7 +2569,9 @@ i386_pseudo_register_read (struct gdbarc
 
 	  /* Extract (always little endian).  We read both lower and
 	     upper registers.  */
-	  regcache_raw_read (regcache, gpnum % 4, raw_buf);
+	  status = regcache_raw_read (regcache, gpnum % 4, raw_buf);
+	  if (status != REG_VALID)
+	    return status;
 	  if (gpnum >= 4)
 	    memcpy (buf, raw_buf + 1, 1);
 	  else
@@ -2569,6 +2580,8 @@ i386_pseudo_register_read (struct gdbarc
       else
 	internal_error (__FILE__, __LINE__, _("invalid regnum"));
     }
+
+  return REG_VALID;
 }
 
 void
Index: src/gdb/amd64-tdep.c
===================================================================
--- src.orig/gdb/amd64-tdep.c	2011-02-21 20:30:32.149344005 +0000
+++ src/gdb/amd64-tdep.c	2011-02-21 21:09:45.459344006 +0000
@@ -275,13 +275,14 @@ amd64_pseudo_register_name (struct gdbar
     return i386_pseudo_register_name (gdbarch, regnum);
 }
 
-static void
+static enum register_status
 amd64_pseudo_register_read (struct gdbarch *gdbarch,
 			    struct regcache *regcache,
 			    int regnum, gdb_byte *buf)
 {
   gdb_byte raw_buf[MAX_REGISTER_SIZE];
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  enum register_status status;
 
   if (i386_byte_regnum_p (gdbarch, regnum))
     {
@@ -291,25 +292,33 @@ amd64_pseudo_register_read (struct gdbar
       if (gpnum >= AMD64_NUM_LOWER_BYTE_REGS)
 	{
 	  /* Special handling for AH, BH, CH, DH.  */
-	  regcache_raw_read (regcache,
-			     gpnum - AMD64_NUM_LOWER_BYTE_REGS, raw_buf);
-	  memcpy (buf, raw_buf + 1, 1);
+	  status = regcache_raw_read (regcache,
+				      gpnum - AMD64_NUM_LOWER_BYTE_REGS,
+				      raw_buf);
+	  if (status == REG_VALID)
+	    memcpy (buf, raw_buf + 1, 1);
 	}
       else
 	{
-	  regcache_raw_read (regcache, gpnum, raw_buf);
-	  memcpy (buf, raw_buf, 1);
+	  status = regcache_raw_read (regcache, gpnum, raw_buf);
+	  if (status == REG_VALID)
+	    memcpy (buf, raw_buf, 1);
 	}
+
+      return status;
     }
   else if (i386_dword_regnum_p (gdbarch, regnum))
     {
       int gpnum = regnum - tdep->eax_regnum;
       /* Extract (always little endian).  */
-      regcache_raw_read (regcache, gpnum, raw_buf);
-      memcpy (buf, raw_buf, 4);
+      status = regcache_raw_read (regcache, gpnum, raw_buf);
+      if (status == REG_VALID)
+	memcpy (buf, raw_buf, 4);
+
+      return status;
     }
   else
-    i386_pseudo_register_read (gdbarch, regcache, regnum, buf);
+    return i386_pseudo_register_read (gdbarch, regcache, regnum, buf);
 }
 
 static void
Index: src/gdb/arm-tdep.c
===================================================================
--- src.orig/gdb/arm-tdep.c	2011-02-21 20:30:32.149344005 +0000
+++ src/gdb/arm-tdep.c	2011-02-21 21:09:45.469344007 +0000
@@ -213,9 +213,9 @@ static void convert_from_extended (const
 static void convert_to_extended (const struct floatformat *, void *,
 				 const void *, int);
 
-static void arm_neon_quad_read (struct gdbarch *gdbarch,
-				struct regcache *regcache,
-				int regnum, gdb_byte *buf);
+static enum register_status arm_neon_quad_read (struct gdbarch *gdbarch,
+						struct regcache *regcache,
+						int regnum, gdb_byte *buf);
 static void arm_neon_quad_write (struct gdbarch *gdbarch,
 				 struct regcache *regcache,
 				 int regnum, const gdb_byte *buf);
@@ -7862,13 +7862,14 @@ arm_write_pc (struct regcache *regcache,
    ABI, even if a NEON unit is not present.  REGNUM is the index of
    the quad register, in [0, 15].  */
 
-static void
+static enum register_status
 arm_neon_quad_read (struct gdbarch *gdbarch, struct regcache *regcache,
 		    int regnum, gdb_byte *buf)
 {
   char name_buf[4];
   gdb_byte reg_buf[8];
   int offset, double_regnum;
+  enum register_status status;
 
   sprintf (name_buf, "d%d", regnum << 1);
   double_regnum = user_reg_map_name_to_regnum (gdbarch, name_buf,
@@ -7880,15 +7881,21 @@ arm_neon_quad_read (struct gdbarch *gdba
   else
     offset = 0;
 
-  regcache_raw_read (regcache, double_regnum, reg_buf);
+  status = regcache_raw_read (regcache, double_regnum, reg_buf);
+  if (status != REG_VALID)
+    return status;
   memcpy (buf + offset, reg_buf, 8);
 
   offset = 8 - offset;
-  regcache_raw_read (regcache, double_regnum + 1, reg_buf);
+  status = regcache_raw_read (regcache, double_regnum + 1, reg_buf);
+  if (status != REG_VALID)
+    return status;
   memcpy (buf + offset, reg_buf, 8);
+
+  return REG_VALID;
 }
 
-static void
+static enum register_status
 arm_pseudo_read (struct gdbarch *gdbarch, struct regcache *regcache,
 		 int regnum, gdb_byte *buf)
 {
@@ -7902,9 +7909,11 @@ arm_pseudo_read (struct gdbarch *gdbarch
 
   if (gdbarch_tdep (gdbarch)->have_neon_pseudos && regnum >= 32 && regnum < 48)
     /* Quad-precision register.  */
-    arm_neon_quad_read (gdbarch, regcache, regnum - 32, buf);
+    return arm_neon_quad_read (gdbarch, regcache, regnum - 32, buf);
   else
     {
+      enum register_status status;
+
       /* Single-precision register.  */
       gdb_assert (regnum < 32);
 
@@ -7918,8 +7927,10 @@ arm_pseudo_read (struct gdbarch *gdbarch
       double_regnum = user_reg_map_name_to_regnum (gdbarch, name_buf,
 						   strlen (name_buf));
 
-      regcache_raw_read (regcache, double_regnum, reg_buf);
-      memcpy (buf, reg_buf + offset, 4);
+      status = regcache_raw_read (regcache, double_regnum, reg_buf);
+      if (status == REG_VALID)
+	memcpy (buf, reg_buf + offset, 4);
+      return status;
     }
 }
 
Index: src/gdb/avr-tdep.c
===================================================================
--- src.orig/gdb/avr-tdep.c	2011-02-21 20:30:32.149344005 +0000
+++ src/gdb/avr-tdep.c	2011-02-21 21:09:45.469344007 +0000
@@ -354,19 +354,22 @@ avr_write_pc (struct regcache *regcache,
                                   avr_convert_iaddr_to_raw (val));
 }
 
-static void
+static enum register_status
 avr_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
                           int regnum, gdb_byte *buf)
 {
   ULONGEST val;
+  enum register_status status;
 
   switch (regnum)
     {
     case AVR_PSEUDO_PC_REGNUM:
-      regcache_raw_read_unsigned (regcache, AVR_PC_REGNUM, &val);
+      status = regcache_raw_read_unsigned (regcache, AVR_PC_REGNUM, &val);
+      if (status != REG_VALID)
+	return status;
       val >>= 1;
       store_unsigned_integer (buf, 4, gdbarch_byte_order (gdbarch), val);
-      break;
+      return status;
     default:
       internal_error (__FILE__, __LINE__, _("invalid regnum"));
     }
Index: src/gdb/frv-tdep.c
===================================================================
--- src.orig/gdb/frv-tdep.c	2011-02-21 20:30:32.149344005 +0000
+++ src/gdb/frv-tdep.c	2011-02-21 21:09:45.469344007 +0000
@@ -300,14 +300,17 @@ frv_register_type (struct gdbarch *gdbar
     return builtin_type (gdbarch)->builtin_int32;
 }
 
-static void
+static enum register_status
 frv_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
                           int reg, gdb_byte *buffer)
 {
+  enum register_status status;
+
   if (reg == iacc0_regnum)
     {
-      regcache_raw_read (regcache, iacc0h_regnum, buffer);
-      regcache_raw_read (regcache, iacc0l_regnum, (bfd_byte *) buffer + 4);
+      status = regcache_raw_read (regcache, iacc0h_regnum, buffer);
+      if (status == REG_VALID)
+	status = regcache_raw_read (regcache, iacc0l_regnum, (bfd_byte *) buffer + 4);
     }
   else if (accg0_regnum <= reg && reg <= accg7_regnum)
     {
@@ -316,14 +319,22 @@ frv_pseudo_register_read (struct gdbarch
 
       int raw_regnum = accg0123_regnum + (reg - accg0_regnum) / 4;
       int byte_num = (reg - accg0_regnum) % 4;
-      bfd_byte buf[4];
+      gdb_byte buf[4];
 
-      regcache_raw_read (regcache, raw_regnum, buf);
-      memset (buffer, 0, 4);
-      /* FR-V is big endian, so put the requested byte in the first byte
-         of the buffer allocated to hold the pseudo-register.  */
-      ((bfd_byte *) buffer)[0] = buf[byte_num];
+      status = regcache_raw_read (regcache, raw_regnum, buf);
+      if (status == REG_VALID)
+	{
+	  memset (buffer, 0, 4);
+	  /* FR-V is big endian, so put the requested byte in the
+	     first byte of the buffer allocated to hold the
+	     pseudo-register.  */
+	  buffer[0] = buf[byte_num];
+	}
     }
+  else
+    gdb_assert_not_reached ("invalid pseudo register number");
+
+  return status;
 }
 
 static void
Index: src/gdb/h8300-tdep.c
===================================================================
--- src.orig/gdb/h8300-tdep.c	2011-02-21 20:30:32.149344005 +0000
+++ src/gdb/h8300-tdep.c	2011-02-21 21:09:45.469344007 +0000
@@ -1149,17 +1149,17 @@ h8300_register_type (struct gdbarch *gdb
     }
 }
 
-static void
+static enum register_status
 h8300_pseudo_register_read (struct gdbarch *gdbarch,
 			    struct regcache *regcache, int regno,
 			    gdb_byte *buf)
 {
   if (regno == E_PSEUDO_CCR_REGNUM (gdbarch))
-    regcache_raw_read (regcache, E_CCR_REGNUM, buf);
+    return regcache_raw_read (regcache, E_CCR_REGNUM, buf);
   else if (regno == E_PSEUDO_EXR_REGNUM (gdbarch))
-    regcache_raw_read (regcache, E_EXR_REGNUM, buf);
+    return regcache_raw_read (regcache, E_EXR_REGNUM, buf);
   else
-    regcache_raw_read (regcache, regno, buf);
+    return regcache_raw_read (regcache, regno, buf);
 }
 
 static void
Index: src/gdb/hppa-tdep.c
===================================================================
--- src.orig/gdb/hppa-tdep.c	2011-02-21 20:30:32.149344005 +0000
+++ src/gdb/hppa-tdep.c	2011-02-21 21:09:45.479344010 +0000
@@ -2665,17 +2665,22 @@ hppa_fetch_pointer_argument (struct fram
   return get_frame_register_unsigned (frame, HPPA_R0_REGNUM + 26 - argi);
 }
 
-static void
+static enum register_status
 hppa_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
 			   int regnum, gdb_byte *buf)
 {
-    enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
-    ULONGEST tmp;
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+  ULONGEST tmp;
+  enum register_status status;
 
-    regcache_raw_read_unsigned (regcache, regnum, &tmp);
-    if (regnum == HPPA_PCOQ_HEAD_REGNUM || regnum == HPPA_PCOQ_TAIL_REGNUM)
-      tmp &= ~0x3;
-    store_unsigned_integer (buf, sizeof tmp, byte_order, tmp);
+  status = regcache_raw_read_unsigned (regcache, regnum, &tmp);
+  if (status == REG_VALID)
+    {
+      if (regnum == HPPA_PCOQ_HEAD_REGNUM || regnum == HPPA_PCOQ_TAIL_REGNUM)
+	tmp &= ~0x3;
+      store_unsigned_integer (buf, sizeof tmp, byte_order, tmp);
+    }
+  return status;
 }
 
 static CORE_ADDR
Index: src/gdb/m32c-tdep.c
===================================================================
--- src.orig/gdb/m32c-tdep.c	2011-02-21 20:30:32.149344005 +0000
+++ src/gdb/m32c-tdep.c	2011-02-21 21:09:45.479344010 +0000
@@ -54,9 +54,9 @@ struct m32c_reg;
 
 /* The type of a function that moves the value of REG between CACHE or
    BUF --- in either direction.  */
-typedef void (m32c_move_reg_t) (struct m32c_reg *reg,
-				struct regcache *cache,
-				void *buf);
+typedef enum register_status (m32c_move_reg_t) (struct m32c_reg *reg,
+						struct regcache *cache,
+						void *buf);
 
 struct m32c_reg
 {
@@ -315,18 +315,20 @@ static m32c_move_reg_t m32c_r3r2r1r0_rea
 
 
 /* Copy the value of the raw register REG from CACHE to BUF.  */
-static void
+static enum register_status
 m32c_raw_read (struct m32c_reg *reg, struct regcache *cache, void *buf)
 {
-  regcache_raw_read (cache, reg->num, buf);
+  return regcache_raw_read (cache, reg->num, buf);
 }
 
 
 /* Copy the value of the raw register REG from BUF to CACHE.  */
-static void
+static enum register_status
 m32c_raw_write (struct m32c_reg *reg, struct regcache *cache, void *buf)
 {
   regcache_raw_write (cache, reg->num, (const void *) buf);
+
+  return REG_VALID;
 }
 
 
@@ -353,11 +355,11 @@ m32c_banked_register (struct m32c_reg *r
    If the value of the 'flg' register in CACHE has any of the bits
    masked in REG->n set, then read REG->ry.  Otherwise, read
    REG->rx.  */
-static void
+static enum register_status
 m32c_banked_read (struct m32c_reg *reg, struct regcache *cache, void *buf)
 {
   struct m32c_reg *bank_reg = m32c_banked_register (reg, cache);
-  regcache_raw_read (cache, bank_reg->num, buf);
+  return regcache_raw_read (cache, bank_reg->num, buf);
 }
 
 
@@ -365,35 +367,39 @@ m32c_banked_read (struct m32c_reg *reg,
    If the value of the 'flg' register in CACHE has any of the bits
    masked in REG->n set, then write REG->ry.  Otherwise, write
    REG->rx.  */
-static void
+static enum register_status
 m32c_banked_write (struct m32c_reg *reg, struct regcache *cache, void *buf)
 {
   struct m32c_reg *bank_reg = m32c_banked_register (reg, cache);
   regcache_raw_write (cache, bank_reg->num, (const void *) buf);
+
+  return REG_VALID;
 }
 
 
 /* Move the value of SB from CACHE to BUF.  On bfd_mach_m32c, SB is a
    banked register; on bfd_mach_m16c, it's not.  */
-static void
+static enum register_status
 m32c_sb_read (struct m32c_reg *reg, struct regcache *cache, void *buf)
 {
   if (gdbarch_bfd_arch_info (reg->arch)->mach == bfd_mach_m16c)
-    m32c_raw_read (reg->rx, cache, buf);
+    return m32c_raw_read (reg->rx, cache, buf);
   else
-    m32c_banked_read (reg, cache, buf);
+    return m32c_banked_read (reg, cache, buf);
 }
 
 
 /* Move the value of SB from BUF to CACHE.  On bfd_mach_m32c, SB is a
    banked register; on bfd_mach_m16c, it's not.  */
-static void
+static enum register_status
 m32c_sb_write (struct m32c_reg *reg, struct regcache *cache, void *buf)
 {
   if (gdbarch_bfd_arch_info (reg->arch)->mach == bfd_mach_m16c)
     m32c_raw_write (reg->rx, cache, buf);
   else
     m32c_banked_write (reg, cache, buf);
+
+  return REG_VALID;
 }
 
 
@@ -438,13 +444,14 @@ m32c_find_part (struct m32c_reg *reg, in
    to BUF.  Treating the value of the register REG->rx as an array of
    REG->type values, where higher indices refer to more significant
    bits, read the value of the REG->n'th element.  */
-static void
+static enum register_status
 m32c_part_read (struct m32c_reg *reg, struct regcache *cache, void *buf)
 {
   int offset, len;
+
   memset (buf, 0, TYPE_LENGTH (reg->type));
   m32c_find_part (reg, &offset, &len);
-  regcache_cooked_read_part (cache, reg->rx->num, offset, len, buf);
+  return regcache_cooked_read_part (cache, reg->rx->num, offset, len, buf);
 }
 
 
@@ -452,45 +459,53 @@ m32c_part_read (struct m32c_reg *reg, st
    Treating the value of the register REG->rx as an array of REG->type
    values, where higher indices refer to more significant bits, write
    the value of the REG->n'th element.  */
-static void
+static enum register_status
 m32c_part_write (struct m32c_reg *reg, struct regcache *cache, void *buf)
 {
   int offset, len;
+
   m32c_find_part (reg, &offset, &len);
   regcache_cooked_write_part (cache, reg->rx->num, offset, len, buf);
+
+  return REG_VALID;
 }
 
 
 /* Move the value of REG from CACHE to BUF.  REG's value is the
    concatenation of the values of the registers REG->rx and REG->ry,
    with REG->rx contributing the more significant bits.  */
-static void
+static enum register_status
 m32c_cat_read (struct m32c_reg *reg, struct regcache *cache, void *buf)
 {
   int high_bytes = TYPE_LENGTH (reg->rx->type);
   int low_bytes  = TYPE_LENGTH (reg->ry->type);
   /* For address arithmetic.  */
   unsigned char *cbuf = buf;
+  enum register_status status;
 
   gdb_assert (TYPE_LENGTH (reg->type) == high_bytes + low_bytes);
 
   if (gdbarch_byte_order (reg->arch) == BFD_ENDIAN_BIG)
     {
-      regcache_cooked_read (cache, reg->rx->num, cbuf);
-      regcache_cooked_read (cache, reg->ry->num, cbuf + high_bytes);
+      status = regcache_cooked_read (cache, reg->rx->num, cbuf);
+      if (status == REG_VALID)
+	status = regcache_cooked_read (cache, reg->ry->num, cbuf + high_bytes);
     }
   else
     {
-      regcache_cooked_read (cache, reg->rx->num, cbuf + low_bytes);
-      regcache_cooked_read (cache, reg->ry->num, cbuf);
+      status = regcache_cooked_read (cache, reg->rx->num, cbuf + low_bytes);
+      if (status == REG_VALID)
+	status = regcache_cooked_read (cache, reg->ry->num, cbuf);
     }
+
+  return status;
 }
 
 
 /* Move the value of REG from CACHE to BUF.  REG's value is the
    concatenation of the values of the registers REG->rx and REG->ry,
    with REG->rx contributing the more significant bits.  */
-static void
+static enum register_status
 m32c_cat_write (struct m32c_reg *reg, struct regcache *cache, void *buf)
 {
   int high_bytes = TYPE_LENGTH (reg->rx->type);
@@ -510,42 +525,53 @@ m32c_cat_write (struct m32c_reg *reg, st
       regcache_cooked_write (cache, reg->rx->num, cbuf + low_bytes);
       regcache_cooked_write (cache, reg->ry->num, cbuf);
     }
+
+  return REG_VALID;
 }
 
 
 /* Copy the value of the raw register REG from CACHE to BUF.  REG is
    the concatenation (from most significant to least) of r3, r2, r1,
    and r0.  */
-static void
+static enum register_status
 m32c_r3r2r1r0_read (struct m32c_reg *reg, struct regcache *cache, void *buf)
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (reg->arch);
   int len = TYPE_LENGTH (tdep->r0->type);
+  enum register_status status;
 
   /* For address arithmetic.  */
   unsigned char *cbuf = buf;
 
   if (gdbarch_byte_order (reg->arch) == BFD_ENDIAN_BIG)
     {
-      regcache_cooked_read (cache, tdep->r0->num, cbuf + len * 3);
-      regcache_cooked_read (cache, tdep->r1->num, cbuf + len * 2);
-      regcache_cooked_read (cache, tdep->r2->num, cbuf + len * 1);
-      regcache_cooked_read (cache, tdep->r3->num, cbuf);
+      status = regcache_cooked_read (cache, tdep->r0->num, cbuf + len * 3);
+      if (status == REG_VALID)
+	status = regcache_cooked_read (cache, tdep->r1->num, cbuf + len * 2);
+      if (status == REG_VALID)
+	status = regcache_cooked_read (cache, tdep->r2->num, cbuf + len * 1);
+      if (status == REG_VALID)
+	status = regcache_cooked_read (cache, tdep->r3->num, cbuf);
     }
   else
     {
-      regcache_cooked_read (cache, tdep->r0->num, cbuf);
-      regcache_cooked_read (cache, tdep->r1->num, cbuf + len * 1);
-      regcache_cooked_read (cache, tdep->r2->num, cbuf + len * 2);
-      regcache_cooked_read (cache, tdep->r3->num, cbuf + len * 3);
+      status = regcache_cooked_read (cache, tdep->r0->num, cbuf);
+      if (status == REG_VALID)
+	status = regcache_cooked_read (cache, tdep->r1->num, cbuf + len * 1);
+      if (status == REG_VALID)
+	status = regcache_cooked_read (cache, tdep->r2->num, cbuf + len * 2);
+      if (status == REG_VALID)
+	status = regcache_cooked_read (cache, tdep->r3->num, cbuf + len * 3);
     }
+
+  return status;
 }
 
 
 /* Copy the value of the raw register REG from BUF to CACHE.  REG is
    the concatenation (from most significant to least) of r3, r2, r1,
    and r0.  */
-static void
+static enum register_status
 m32c_r3r2r1r0_write (struct m32c_reg *reg, struct regcache *cache, void *buf)
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (reg->arch);
@@ -568,10 +594,12 @@ m32c_r3r2r1r0_write (struct m32c_reg *re
       regcache_cooked_write (cache, tdep->r2->num, cbuf + len * 2);
       regcache_cooked_write (cache, tdep->r3->num, cbuf + len * 3);
     }
+
+  return REG_VALID;
 }
 
 
-static void
+static enum register_status
 m32c_pseudo_register_read (struct gdbarch *arch,
 			   struct regcache *cache,
 			   int cookednum,
@@ -585,7 +613,7 @@ m32c_pseudo_register_read (struct gdbarc
   gdb_assert (arch == tdep->regs[cookednum].arch);
   reg = &tdep->regs[cookednum];
 
-  reg->read (reg, cache, buf);
+  return reg->read (reg, cache, buf);
 }
 
 
Index: src/gdb/m68hc11-tdep.c
===================================================================
--- src.orig/gdb/m68hc11-tdep.c	2011-02-21 20:30:32.149344005 +0000
+++ src/gdb/m68hc11-tdep.c	2011-02-21 21:09:45.479344010 +0000
@@ -279,7 +279,7 @@ m68hc11_which_soft_register (CORE_ADDR a
 /* Fetch a pseudo register.  The 68hc11 soft registers are treated like
    pseudo registers.  They are located in memory.  Translate the register
    fetch into a memory read.  */
-static void
+static enum register_status
 m68hc11_pseudo_register_read (struct gdbarch *gdbarch,
 			      struct regcache *regcache,
 			      int regno, gdb_byte *buf)
@@ -292,8 +292,11 @@ m68hc11_pseudo_register_read (struct gdb
     {
       ULONGEST pc;
       const int regsize = 4;
+      enum register_status status;
 
-      regcache_cooked_read_unsigned (regcache, HARD_PC_REGNUM, &pc);
+      status = regcache_cooked_read_unsigned (regcache, HARD_PC_REGNUM, &pc);
+      if (status != REG_VALID)
+	return status;
       if (pc >= 0x8000 && pc < 0xc000)
         {
           ULONGEST page;
@@ -304,7 +307,7 @@ m68hc11_pseudo_register_read (struct gdb
           pc += 0x1000000;
         }
       store_unsigned_integer (buf, regsize, byte_order, pc);
-      return;
+      return REG_VALID;
     }
 
   m68hc11_initialize_register_info ();
@@ -318,6 +321,8 @@ m68hc11_pseudo_register_read (struct gdb
     {
       memset (buf, 0, 2);
     }
+
+  return REG_VALID;
 }
 
 /* Store a pseudo register.  Translate the register store
Index: src/gdb/mep-tdep.c
===================================================================
--- src.orig/gdb/mep-tdep.c	2011-02-21 20:30:32.149344005 +0000
+++ src/gdb/mep-tdep.c	2011-02-21 21:09:45.479344010 +0000
@@ -1133,12 +1133,13 @@ mep_write_pc (struct regcache *regcache,
 }
 
 
-static void
+static enum register_status
 mep_pseudo_cr32_read (struct gdbarch *gdbarch,
                       struct regcache *regcache,
                       int cookednum,
                       void *buf)
 {
+  enum register_status status;
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   /* Read the raw register into a 64-bit buffer, and then return the
      appropriate end of that buffer.  */
@@ -1147,24 +1148,28 @@ mep_pseudo_cr32_read (struct gdbarch *gd
 
   gdb_assert (TYPE_LENGTH (register_type (gdbarch, rawnum)) == sizeof (buf64));
   gdb_assert (TYPE_LENGTH (register_type (gdbarch, cookednum)) == 4);
-  regcache_raw_read (regcache, rawnum, buf64);
-  /* Slow, but legible.  */
-  store_unsigned_integer (buf, 4, byte_order,
-			  extract_unsigned_integer (buf64, 8, byte_order));
+  status = regcache_raw_read (regcache, rawnum, buf64);
+  if (status == REG_VALID)
+    {
+      /* Slow, but legible.  */
+      store_unsigned_integer (buf, 4, byte_order,
+			      extract_unsigned_integer (buf64, 8, byte_order));
+    }
+  return status;
 }
 
 
-static void
+static enum register_status
 mep_pseudo_cr64_read (struct gdbarch *gdbarch,
                       struct regcache *regcache,
                       int cookednum,
                       void *buf)
 {
-  regcache_raw_read (regcache, mep_pseudo_to_raw[cookednum], buf);
+  return regcache_raw_read (regcache, mep_pseudo_to_raw[cookednum], buf);
 }
 
 
-static void
+static enum register_status
 mep_pseudo_register_read (struct gdbarch *gdbarch,
                           struct regcache *regcache,
                           int cookednum,
@@ -1172,13 +1177,13 @@ mep_pseudo_register_read (struct gdbarch
 {
   if (IS_CSR_REGNUM (cookednum)
       || IS_CCR_REGNUM (cookednum))
-    regcache_raw_read (regcache, mep_pseudo_to_raw[cookednum], buf);
+    return regcache_raw_read (regcache, mep_pseudo_to_raw[cookednum], buf);
   else if (IS_CR32_REGNUM (cookednum)
            || IS_FP_CR32_REGNUM (cookednum))
-    mep_pseudo_cr32_read (gdbarch, regcache, cookednum, buf);
+    return mep_pseudo_cr32_read (gdbarch, regcache, cookednum, buf);
   else if (IS_CR64_REGNUM (cookednum)
            || IS_FP_CR64_REGNUM (cookednum))
-    mep_pseudo_cr64_read (gdbarch, regcache, cookednum, buf);
+    return mep_pseudo_cr64_read (gdbarch, regcache, cookednum, buf);
   else
     gdb_assert_not_reached ("unexpected pseudo register");
 }
Index: src/gdb/mips-tdep.c
===================================================================
--- src.orig/gdb/mips-tdep.c	2011-02-21 20:30:32.149344005 +0000
+++ src/gdb/mips-tdep.c	2011-02-21 21:09:45.479344010 +0000
@@ -564,7 +564,7 @@ mips_tdesc_register_reggroup_p (struct g
    gdbarch_num_regs .. 2 * gdbarch_num_regs) back onto the corresponding raw
    registers.  Take care of alignment and size problems.  */
 
-static void
+static enum register_status
 mips_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
 			   int cookednum, gdb_byte *buf)
 {
@@ -572,18 +572,22 @@ mips_pseudo_register_read (struct gdbarc
   gdb_assert (cookednum >= gdbarch_num_regs (gdbarch)
 	      && cookednum < 2 * gdbarch_num_regs (gdbarch));
   if (register_size (gdbarch, rawnum) == register_size (gdbarch, cookednum))
-    regcache_raw_read (regcache, rawnum, buf);
+    return regcache_raw_read (regcache, rawnum, buf);
   else if (register_size (gdbarch, rawnum) >
 	   register_size (gdbarch, cookednum))
     {
       if (gdbarch_tdep (gdbarch)->mips64_transfers_32bit_regs_p)
-	regcache_raw_read_part (regcache, rawnum, 0, 4, buf);
+	return regcache_raw_read_part (regcache, rawnum, 0, 4, buf);
       else
 	{
 	  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
 	  LONGEST regval;
-	  regcache_raw_read_signed (regcache, rawnum, &regval);
-	  store_signed_integer (buf, 4, byte_order, regval);
+	  enum register_status status;
+
+	  status = regcache_raw_read_signed (regcache, rawnum, &regval);
+	  if (status == REG_VALID)
+	    store_signed_integer (buf, 4, byte_order, regval);
+	  return status;
 	}
     }
   else
Index: src/gdb/mt-tdep.c
===================================================================
--- src.orig/gdb/mt-tdep.c	2011-02-21 20:30:32.149344005 +0000
+++ src/gdb/mt-tdep.c	2011-02-21 21:09:45.479344010 +0000
@@ -524,9 +524,9 @@ mt_select_coprocessor (struct gdbarch *g
    Additionally there is an array of coprocessor registers which track
    the coprocessor registers for each coprocessor.  */
 
-static void
+static enum register_status
 mt_pseudo_register_read (struct gdbarch *gdbarch,
-			  struct regcache *regcache, int regno, gdb_byte *buf)
+			 struct regcache *regcache, int regno, gdb_byte *buf)
 {
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
 
@@ -534,34 +534,45 @@ mt_pseudo_register_read (struct gdbarch
     {
     case MT_COPRO_REGNUM:
     case MT_COPRO_PSEUDOREG_REGNUM:
-      regcache_raw_read (regcache, MT_COPRO_REGNUM, buf);
-      break;
+      return regcache_raw_read (regcache, MT_COPRO_REGNUM, buf);
     case MT_MAC_REGNUM:
     case MT_MAC_PSEUDOREG_REGNUM:
       if (gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_mrisc2
 	  || gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_ms2)
 	{
+	  enum register_status status;
 	  ULONGEST oldmac = 0, ext_mac = 0;
 	  ULONGEST newmac;
 
-	  regcache_cooked_read_unsigned (regcache, MT_MAC_REGNUM, &oldmac);
+	  status = regcache_cooked_read_unsigned (regcache, MT_MAC_REGNUM, &oldmac);
+	  if (status != REG_VALID)
+	    return status;
+
 	  regcache_cooked_read_unsigned (regcache, MT_EXMAC_REGNUM, &ext_mac);
+	  if (status != REG_VALID)
+	    return status;
+
 	  newmac =
 	    (oldmac & 0xffffffff) | ((long long) (ext_mac & 0xff) << 32);
 	  store_signed_integer (buf, 8, byte_order, newmac);
+
+	  return REG_VALID;
 	}
       else
-	regcache_raw_read (regcache, MT_MAC_REGNUM, buf);
+	return regcache_raw_read (regcache, MT_MAC_REGNUM, buf);
       break;
     default:
       {
 	unsigned index = mt_select_coprocessor (gdbarch, regcache, regno);
 	
 	if (index == MT_COPRO_PSEUDOREG_MAC_REGNUM)
-	  mt_pseudo_register_read (gdbarch, regcache,
-				   MT_MAC_PSEUDOREG_REGNUM, buf);
+	  return mt_pseudo_register_read (gdbarch, regcache,
+					  MT_MAC_PSEUDOREG_REGNUM, buf);
 	else if (index < MT_NUM_REGS - MT_CPR0_REGNUM)
-	  regcache_raw_read (regcache, index + MT_CPR0_REGNUM, buf);
+	  return regcache_raw_read (regcache, index + MT_CPR0_REGNUM, buf);
+	else
+	  /* ??? */
+	  return REG_VALID;
       }
       break;
     }
Index: src/gdb/rs6000-tdep.c
===================================================================
--- src.orig/gdb/rs6000-tdep.c	2011-02-21 20:30:32.149344005 +0000
+++ src/gdb/rs6000-tdep.c	2011-02-21 21:09:45.489344004 +0000
@@ -2536,6 +2536,11 @@ rs6000_value_to_register (struct frame_i
   put_frame_register (frame, regnum, to);
 }
 
+ /* The type of a function that moves the value of REG between CACHE
+    or BUF --- in either direction.  */
+typedef enum register_status (*move_ev_register_func) (struct regcache *,
+						       int, void *);
+
 /* Move SPE vector register values between a 64-bit buffer and the two
    32-bit raw register halves in a regcache.  This function handles
    both splitting a 64-bit value into two 32-bit halves, and joining
@@ -2559,16 +2564,16 @@ rs6000_value_to_register (struct frame_i
    MOVE, since this function can't tell at compile-time which of
    REGCACHE or BUFFER is acting as the source of the data.  If C had
    co-variant type qualifiers, ...  */
-static void
-e500_move_ev_register (void (*move) (struct regcache *regcache,
-                                     int regnum, gdb_byte *buf),
-                       struct regcache *regcache, int ev_reg,
-                       gdb_byte *buffer)
+
+static enum register_status
+e500_move_ev_register (move_ev_register_func move,
+		       struct regcache *regcache, int ev_reg, void *buffer)
 {
   struct gdbarch *arch = get_regcache_arch (regcache);
   struct gdbarch_tdep *tdep = gdbarch_tdep (arch); 
   int reg_index;
   gdb_byte *byte_buffer = buffer;
+  enum register_status status;
 
   gdb_assert (IS_SPE_PSEUDOREG (tdep, ev_reg));
 
@@ -2576,55 +2581,80 @@ e500_move_ev_register (void (*move) (str
 
   if (gdbarch_byte_order (arch) == BFD_ENDIAN_BIG)
     {
-      move (regcache, tdep->ppc_ev0_upper_regnum + reg_index, byte_buffer);
-      move (regcache, tdep->ppc_gp0_regnum + reg_index, byte_buffer + 4);
+      status = move (regcache, tdep->ppc_ev0_upper_regnum + reg_index,
+		     byte_buffer);
+      if (status == REG_VALID)
+	status = move (regcache, tdep->ppc_gp0_regnum + reg_index,
+		       byte_buffer + 4);
     }
   else
     {
-      move (regcache, tdep->ppc_gp0_regnum + reg_index, byte_buffer);
-      move (regcache, tdep->ppc_ev0_upper_regnum + reg_index, byte_buffer + 4);
+      status = move (regcache, tdep->ppc_gp0_regnum + reg_index, byte_buffer);
+      if (status == REG_VALID)
+	status = move (regcache, tdep->ppc_ev0_upper_regnum + reg_index,
+		       byte_buffer + 4);
     }
+
+  return status;
 }
 
-static void
+static enum register_status
+do_regcache_raw_read (struct regcache *regcache, int regnum, void *buffer)
+{
+  return regcache_raw_read (regcache, regnum, buffer);
+}
+
+static enum register_status
+do_regcache_raw_write (struct regcache *regcache, int regnum, void *buffer)
+{
+  regcache_raw_write (regcache, regnum, buffer);
+
+  return REG_VALID;
+}
+
+static enum register_status
 e500_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
 			   int reg_nr, gdb_byte *buffer)
 {
-  e500_move_ev_register (regcache_raw_read, regcache, reg_nr, buffer);
+  return e500_move_ev_register (do_regcache_raw_read, regcache, reg_nr, buffer);
 }
 
 static void
 e500_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
 			    int reg_nr, const gdb_byte *buffer)
 {
-  e500_move_ev_register ((void (*) (struct regcache *, int, gdb_byte *))
-			 regcache_raw_write,
-			 regcache, reg_nr, (gdb_byte *) buffer);
+  e500_move_ev_register (do_regcache_raw_write, regcache,
+			 reg_nr, (void *) buffer);
 }
 
 /* Read method for DFP pseudo-registers.  */
-static void
+static enum register_status
 dfp_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
 			   int reg_nr, gdb_byte *buffer)
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   int reg_index = reg_nr - tdep->ppc_dl0_regnum;
+  enum register_status status;
 
   if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
     {
       /* Read two FP registers to form a whole dl register.  */
-      regcache_raw_read (regcache, tdep->ppc_fp0_regnum +
-			 2 * reg_index, buffer);
-      regcache_raw_read (regcache, tdep->ppc_fp0_regnum +
-			 2 * reg_index + 1, buffer + 8);
+      status = regcache_raw_read (regcache, tdep->ppc_fp0_regnum +
+				  2 * reg_index, buffer);
+      if (status == REG_VALID)
+	status = regcache_raw_read (regcache, tdep->ppc_fp0_regnum +
+				    2 * reg_index + 1, buffer + 8);
     }
   else
     {
-      regcache_raw_read (regcache, tdep->ppc_fp0_regnum +
-			 2 * reg_index + 1, buffer + 8);
-      regcache_raw_read (regcache, tdep->ppc_fp0_regnum +
-			 2 * reg_index, buffer);
+      status = regcache_raw_read (regcache, tdep->ppc_fp0_regnum +
+				  2 * reg_index + 1, buffer + 8);
+      if (status == REG_VALID)
+	status = regcache_raw_read (regcache, tdep->ppc_fp0_regnum +
+				    2 * reg_index, buffer);
     }
+
+  return status;
 }
 
 /* Write method for DFP pseudo-registers.  */
@@ -2654,33 +2684,38 @@ dfp_pseudo_register_write (struct gdbarc
 }
 
 /* Read method for POWER7 VSX pseudo-registers.  */
-static void
+static enum register_status
 vsx_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
 			   int reg_nr, gdb_byte *buffer)
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   int reg_index = reg_nr - tdep->ppc_vsr0_regnum;
+  enum register_status status;
 
   /* Read the portion that overlaps the VMX registers.  */
   if (reg_index > 31)
-    regcache_raw_read (regcache, tdep->ppc_vr0_regnum +
-			reg_index - 32, buffer);
+    status = regcache_raw_read (regcache, tdep->ppc_vr0_regnum +
+				reg_index - 32, buffer);
   else
     /* Read the portion that overlaps the FPR registers.  */
     if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
       {
-	regcache_raw_read (regcache, tdep->ppc_fp0_regnum +
-			reg_index, buffer);
-	regcache_raw_read (regcache, tdep->ppc_vsr0_upper_regnum +
-			reg_index, buffer + 8);
+	status = regcache_raw_read (regcache, tdep->ppc_fp0_regnum +
+				    reg_index, buffer);
+	if (status == REG_VALID)
+	  status = regcache_raw_read (regcache, tdep->ppc_vsr0_upper_regnum +
+				      reg_index, buffer + 8);
       }
     else
       {
-	regcache_raw_read (regcache, tdep->ppc_fp0_regnum +
-			reg_index, buffer + 8);
-	regcache_raw_read (regcache, tdep->ppc_vsr0_upper_regnum +
-			reg_index, buffer);
+	status = regcache_raw_read (regcache, tdep->ppc_fp0_regnum +
+				    reg_index, buffer + 8);
+	if (status == REG_VALID)
+	  status = regcache_raw_read (regcache, tdep->ppc_vsr0_upper_regnum +
+				      reg_index, buffer);
       }
+
+  return status;
 }
 
 /* Write method for POWER7 VSX pseudo-registers.  */
@@ -2714,7 +2749,7 @@ vsx_pseudo_register_write (struct gdbarc
 }
 
 /* Read method for POWER7 Extended FP pseudo-registers.  */
-static void
+static enum register_status
 efpr_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
 			   int reg_nr, gdb_byte *buffer)
 {
@@ -2722,8 +2757,8 @@ efpr_pseudo_register_read (struct gdbarc
   int reg_index = reg_nr - tdep->ppc_efpr0_regnum;
 
   /* Read the portion that overlaps the VMX register.  */
-  regcache_raw_read_part (regcache, tdep->ppc_vr0_regnum + reg_index, 0,
-			  register_size (gdbarch, reg_nr), buffer);
+  return regcache_raw_read_part (regcache, tdep->ppc_vr0_regnum + reg_index, 0,
+				 register_size (gdbarch, reg_nr), buffer);
 }
 
 /* Write method for POWER7 Extended FP pseudo-registers.  */
@@ -2739,7 +2774,7 @@ efpr_pseudo_register_write (struct gdbar
 			   register_size (gdbarch, reg_nr), buffer);
 }
 
-static void
+static enum register_status
 rs6000_pseudo_register_read (struct gdbarch *gdbarch,
 			     struct regcache *regcache,
 			     int reg_nr, gdb_byte *buffer)
@@ -2750,13 +2785,13 @@ rs6000_pseudo_register_read (struct gdba
   gdb_assert (regcache_arch == gdbarch);
 
   if (IS_SPE_PSEUDOREG (tdep, reg_nr))
-    e500_pseudo_register_read (gdbarch, regcache, reg_nr, buffer);
+    return e500_pseudo_register_read (gdbarch, regcache, reg_nr, buffer);
   else if (IS_DFP_PSEUDOREG (tdep, reg_nr))
-    dfp_pseudo_register_read (gdbarch, regcache, reg_nr, buffer);
+    return dfp_pseudo_register_read (gdbarch, regcache, reg_nr, buffer);
   else if (IS_VSX_PSEUDOREG (tdep, reg_nr))
-    vsx_pseudo_register_read (gdbarch, regcache, reg_nr, buffer);
+    return vsx_pseudo_register_read (gdbarch, regcache, reg_nr, buffer);
   else if (IS_EFP_PSEUDOREG (tdep, reg_nr))
-    efpr_pseudo_register_read (gdbarch, regcache, reg_nr, buffer);
+    return efpr_pseudo_register_read (gdbarch, regcache, reg_nr, buffer);
   else
     internal_error (__FILE__, __LINE__,
 		    _("rs6000_pseudo_register_read: "
Index: src/gdb/s390-tdep.c
===================================================================
--- src.orig/gdb/s390-tdep.c	2011-02-21 20:30:32.149344005 +0000
+++ src/gdb/s390-tdep.c	2011-02-21 21:09:45.489344004 +0000
@@ -216,7 +216,7 @@ s390_pseudo_register_type (struct gdbarc
   internal_error (__FILE__, __LINE__, _("invalid regnum"));
 }
 
-static void
+static enum register_status
 s390_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
 			   int regnum, gdb_byte *buf)
 {
@@ -227,37 +227,53 @@ s390_pseudo_register_read (struct gdbarc
 
   if (regnum == tdep->pc_regnum)
     {
-      regcache_raw_read_unsigned (regcache, S390_PSWA_REGNUM, &val);
-      if (register_size (gdbarch, S390_PSWA_REGNUM) == 4)
-	val &= 0x7fffffff;
-      store_unsigned_integer (buf, regsize, byte_order, val);
-      return;
+      enum register_status status;
+
+      status = regcache_raw_read_unsigned (regcache, S390_PSWA_REGNUM, &val);
+      if (status == REG_VALID)
+	{
+	  if (register_size (gdbarch, S390_PSWA_REGNUM) == 4)
+	    val &= 0x7fffffff;
+	  store_unsigned_integer (buf, regsize, byte_order, val);
+	}
+      return status;
     }
 
   if (regnum == tdep->cc_regnum)
     {
-      regcache_raw_read_unsigned (regcache, S390_PSWM_REGNUM, &val);
-      if (register_size (gdbarch, S390_PSWA_REGNUM) == 4)
-	val = (val >> 12) & 3;
-      else
-	val = (val >> 44) & 3;
-      store_unsigned_integer (buf, regsize, byte_order, val);
-      return;
+      enum register_status status;
+
+      status = regcache_raw_read_unsigned (regcache, S390_PSWM_REGNUM, &val);
+      if (status == REG_VALID)
+	{
+	  if (register_size (gdbarch, S390_PSWA_REGNUM) == 4)
+	    val = (val >> 12) & 3;
+	  else
+	    val = (val >> 44) & 3;
+	  store_unsigned_integer (buf, regsize, byte_order, val);
+	}
+      return status;
     }
 
   if (tdep->gpr_full_regnum != -1
       && regnum >= tdep->gpr_full_regnum
       && regnum < tdep->gpr_full_regnum + 16)
     {
+      enum register_status status;
       ULONGEST val_upper;
+
       regnum -= tdep->gpr_full_regnum;
 
-      regcache_raw_read_unsigned (regcache, S390_R0_REGNUM + regnum, &val);
-      regcache_raw_read_unsigned (regcache, S390_R0_UPPER_REGNUM + regnum,
-				  &val_upper);
-      val |= val_upper << 32;
-      store_unsigned_integer (buf, regsize, byte_order, val);
-      return;
+      status = regcache_raw_read_unsigned (regcache, S390_R0_REGNUM + regnum, &val);
+      if (status == REG_VALID)
+	status = regcache_raw_read_unsigned (regcache, S390_R0_UPPER_REGNUM + regnum,
+					     &val_upper);
+      if (status == REG_VALID)
+	{
+	  val |= val_upper << 32;
+	  store_unsigned_integer (buf, regsize, byte_order, val);
+	}
+      return status;
     }
 
   internal_error (__FILE__, __LINE__, _("invalid regnum"));
Index: src/gdb/sh64-tdep.c
===================================================================
--- src.orig/gdb/sh64-tdep.c	2011-02-21 20:30:32.149344005 +0000
+++ src/gdb/sh64-tdep.c	2011-02-21 21:09:45.489344004 +0000
@@ -1619,15 +1619,40 @@ sh64_register_convert_to_raw (struct gdb
 	     "with non DR register number"));
 }
 
-static void
+/* Concatenate PORTIONS contiguous raw registers starting at
+   BASE_REGNUM into BUFFER.  */
+
+static enum register_status
+pseudo_register_read_portions (struct gdbarch *gdbarch,
+			       struct regcache *regcache,
+			       int portions,
+			       int base_regnum, gdb_byte *buffer)
+{
+  int portion;
+
+  for (portion = 0; portion < portions; portion++)
+    {
+      enum register_status status;
+      gdb_byte *b;
+
+      b = buffer + register_size (gdbarch, base_regnum) * portion;
+      status = regcache_raw_read (regcache, base_regnum + portion, b);
+      if (status != REG_VALID)
+	return status;
+    }
+
+  return REG_VALID;
+}
+
+static enum register_status
 sh64_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
 			   int reg_nr, gdb_byte *buffer)
 {
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   int base_regnum;
-  int portion;
   int offset = 0;
   char temp_buffer[MAX_REGISTER_SIZE];
+  enum register_status status;
 
   if (reg_nr >= DR0_REGNUM 
       && reg_nr <= DR_LAST_REGNUM)
@@ -1637,19 +1662,20 @@ sh64_pseudo_register_read (struct gdbarc
       /* Build the value in the provided buffer.  */ 
       /* DR regs are double precision registers obtained by
 	 concatenating 2 single precision floating point registers.  */
-      for (portion = 0; portion < 2; portion++)
-	regcache_raw_read (regcache, base_regnum + portion, 
-			   (temp_buffer
-			    + register_size (gdbarch, base_regnum) * portion));
-
-      /* We must pay attention to the endianness.  */
-      sh64_register_convert_to_virtual (gdbarch, reg_nr,
-					register_type (gdbarch, reg_nr),
-					temp_buffer, buffer);
+      status = pseudo_register_read_portions (gdbarch, regcache,
+					      2, base_regnum, temp_buffer);
+      if (status == REG_VALID)
+	{
+	  /* We must pay attention to the endianness.  */
+	  sh64_register_convert_to_virtual (gdbarch, reg_nr,
+					    register_type (gdbarch, reg_nr),
+					    temp_buffer, buffer);
+	}
 
+      return status;
     }
 
-  else if (reg_nr >= FPP0_REGNUM 
+  else if (reg_nr >= FPP0_REGNUM
 	   && reg_nr <= FPP_LAST_REGNUM)
     {
       base_regnum = sh64_fpp_reg_base_num (gdbarch, reg_nr);
@@ -1657,10 +1683,8 @@ sh64_pseudo_register_read (struct gdbarc
       /* Build the value in the provided buffer.  */ 
       /* FPP regs are pairs of single precision registers obtained by
 	 concatenating 2 single precision floating point registers.  */
-      for (portion = 0; portion < 2; portion++)
-	regcache_raw_read (regcache, base_regnum + portion, 
-			   ((char *) buffer
-			    + register_size (gdbarch, base_regnum) * portion));
+      return pseudo_register_read_portions (gdbarch, regcache,
+					    2, base_regnum, buffer);
     }
 
   else if (reg_nr >= FV0_REGNUM 
@@ -1671,10 +1695,8 @@ sh64_pseudo_register_read (struct gdbarc
       /* Build the value in the provided buffer.  */ 
       /* FV regs are vectors of single precision registers obtained by
 	 concatenating 4 single precision floating point registers.  */
-      for (portion = 0; portion < 4; portion++)
-	regcache_raw_read (regcache, base_regnum + portion, 
-			   ((char *) buffer
-			    + register_size (gdbarch, base_regnum) * portion));
+      return pseudo_register_read_portions (gdbarch, regcache,
+					    4, base_regnum, buffer);
     }
 
   /* sh compact pseudo registers.  1-to-1 with a shmedia register.  */
@@ -1684,11 +1706,14 @@ sh64_pseudo_register_read (struct gdbarc
       base_regnum = sh64_compact_reg_base_num (gdbarch, reg_nr);
 
       /* Build the value in the provided buffer.  */ 
-      regcache_raw_read (regcache, base_regnum, temp_buffer);
+      status = regcache_raw_read (regcache, base_regnum, temp_buffer);
+      if (status != REG_VALID)
+	return status;
       if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
 	offset = 4;
       memcpy (buffer,
 	      temp_buffer + offset, 4); /* get LOWER 32 bits only????  */
+      return REG_VALID;
     }
 
   else if (reg_nr >= FP0_C_REGNUM
@@ -1699,7 +1724,7 @@ sh64_pseudo_register_read (struct gdbarc
       /* Build the value in the provided buffer.  */ 
       /* Floating point registers map 1-1 to the media fp regs,
 	 they have the same size and endianness.  */
-      regcache_raw_read (regcache, base_regnum, buffer);
+      return regcache_raw_read (regcache, base_regnum, buffer);
     }
 
   else if (reg_nr >= DR0_C_REGNUM 
@@ -1709,15 +1734,16 @@ sh64_pseudo_register_read (struct gdbarc
 
       /* DR_C regs are double precision registers obtained by
 	 concatenating 2 single precision floating point registers.  */
-      for (portion = 0; portion < 2; portion++)
-	regcache_raw_read (regcache, base_regnum + portion, 
-			   (temp_buffer
-			    + register_size (gdbarch, base_regnum) * portion));
-
-      /* We must pay attention to the endianness.  */
-      sh64_register_convert_to_virtual (gdbarch, reg_nr, 
-					register_type (gdbarch, reg_nr),
-					temp_buffer, buffer);
+      status = pseudo_register_read_portions (gdbarch, regcache,
+					      2, base_regnum, temp_buffer);
+      if (status == REG_VALID)
+	{
+	  /* We must pay attention to the endianness.  */
+	  sh64_register_convert_to_virtual (gdbarch, reg_nr,
+					    register_type (gdbarch, reg_nr),
+					    temp_buffer, buffer);
+	}
+      return status;
     }
 
   else if (reg_nr >= FV0_C_REGNUM 
@@ -1728,10 +1754,8 @@ sh64_pseudo_register_read (struct gdbarc
       /* Build the value in the provided buffer.  */ 
       /* FV_C regs are vectors of single precision registers obtained by
 	 concatenating 4 single precision floating point registers.  */
-      for (portion = 0; portion < 4; portion++)
-	regcache_raw_read (regcache, base_regnum + portion, 
-			   ((char *) buffer
-			    + register_size (gdbarch, base_regnum) * portion));
+      return pseudo_register_read_portions (gdbarch, regcache,
+					    4, base_regnum, buffer);
     }
 
   else if (reg_nr == FPSCR_C_REGNUM)
@@ -1762,11 +1786,15 @@ sh64_pseudo_register_read (struct gdbarc
        */
       /* *INDENT-ON* */
       /* Get FPSCR into a local buffer.  */
-      regcache_raw_read (regcache, fpscr_base_regnum, temp_buffer);
+      status = regcache_raw_read (regcache, fpscr_base_regnum, temp_buffer);
+      if (status != REG_VALID)
+	return status;
       /* Get value as an int.  */
       fpscr_value = extract_unsigned_integer (temp_buffer, 4, byte_order);
       /* Get SR into a local buffer */
-      regcache_raw_read (regcache, sr_base_regnum, temp_buffer);
+      status = regcache_raw_read (regcache, sr_base_regnum, temp_buffer);
+      if (status != REG_VALID)
+	return status;
       /* Get value as an int.  */
       sr_value = extract_unsigned_integer (temp_buffer, 4, byte_order);
       /* Build the new value.  */
@@ -1776,6 +1804,8 @@ sh64_pseudo_register_read (struct gdbarc
       /* Store that in out buffer!!!  */
       store_unsigned_integer (buffer, 4, byte_order, fpscr_c_value);
       /* FIXME There is surely an endianness gotcha here.  */
+
+      return REG_VALID;
     }
 
   else if (reg_nr == FPUL_C_REGNUM)
@@ -1784,8 +1814,10 @@ sh64_pseudo_register_read (struct gdbarc
 
       /* FPUL_C register is floating point register 32,
 	 same size, same endianness.  */
-      regcache_raw_read (regcache, base_regnum, buffer);
+      return regcache_raw_read (regcache, base_regnum, buffer);
     }
+  else
+    gdb_assert_not_reached ("invalid pseudo register number");
 }
 
 static void
Index: src/gdb/ia64-tdep.c
===================================================================
--- src.orig/gdb/ia64-tdep.c	2011-02-21 20:30:32.149344005 +0000
+++ src/gdb/ia64-tdep.c	2011-02-21 21:09:45.489344004 +0000
@@ -933,11 +933,12 @@ rse_address_add(CORE_ADDR addr, int nslo
   return new_addr;
 }
 
-static void
+static enum register_status
 ia64_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
                            int regnum, gdb_byte *buf)
 {
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+  enum register_status status;
 
   if (regnum >= V32_REGNUM && regnum <= V127_REGNUM)
     {
@@ -952,12 +953,21 @@ ia64_pseudo_register_read (struct gdbarc
 	     found sequentially in memory starting at $bof.  This
 	     isn't always true, but without libunwind, this is the
 	     best we can do.  */
+	  enum register_status status;
 	  ULONGEST cfm;
 	  ULONGEST bsp;
 	  CORE_ADDR reg;
-	  regcache_cooked_read_unsigned (regcache, IA64_BSP_REGNUM, &bsp);
-	  regcache_cooked_read_unsigned (regcache, IA64_CFM_REGNUM, &cfm);
-	  
+
+	  status = regcache_cooked_read_unsigned (regcache,
+						  IA64_BSP_REGNUM, &bsp);
+	  if (status != REG_VALID)
+	    return status;
+
+	  status = regcache_cooked_read_unsigned (regcache,
+						  IA64_CFM_REGNUM, &cfm);
+	  if (status != REG_VALID)
+	    return status;
+
 	  /* The bsp points at the end of the register frame so we
 	     subtract the size of frame from it to get start of
 	     register frame.  */
@@ -979,7 +989,9 @@ ia64_pseudo_register_read (struct gdbarc
     {
       ULONGEST unatN_val;
       ULONGEST unat;
-      regcache_cooked_read_unsigned (regcache, IA64_UNAT_REGNUM, &unat);
+      status = regcache_cooked_read_unsigned (regcache, IA64_UNAT_REGNUM, &unat);
+      if (status != REG_VALID)
+	return status;
       unatN_val = (unat & (1LL << (regnum - IA64_NAT0_REGNUM))) != 0;
       store_unsigned_integer (buf, register_size (gdbarch, regnum),
 			      byte_order, unatN_val);
@@ -990,8 +1002,12 @@ ia64_pseudo_register_read (struct gdbarc
       ULONGEST bsp;
       ULONGEST cfm;
       CORE_ADDR gr_addr = 0;
-      regcache_cooked_read_unsigned (regcache, IA64_BSP_REGNUM, &bsp);
-      regcache_cooked_read_unsigned (regcache, IA64_CFM_REGNUM, &cfm);
+      status = regcache_cooked_read_unsigned (regcache, IA64_BSP_REGNUM, &bsp);
+      if (status != REG_VALID)
+	return status;
+      status = regcache_cooked_read_unsigned (regcache, IA64_CFM_REGNUM, &cfm);
+      if (status != REG_VALID)
+	return status;
 
       /* The bsp points at the end of the register frame so we
 	 subtract the size of frame from it to get start of register frame.  */
@@ -1028,8 +1044,12 @@ ia64_pseudo_register_read (struct gdbarc
       ULONGEST bsp, vbsp;
       ULONGEST cfm;
       CORE_ADDR reg;
-      regcache_cooked_read_unsigned (regcache, IA64_BSP_REGNUM, &bsp);
-      regcache_cooked_read_unsigned (regcache, IA64_CFM_REGNUM, &cfm);
+      status = regcache_cooked_read_unsigned (regcache, IA64_BSP_REGNUM, &bsp);
+      if (status != REG_VALID)
+	return status;
+      status = regcache_cooked_read_unsigned (regcache, IA64_CFM_REGNUM, &cfm);
+      if (status != REG_VALID)
+	return status;
 
       /* The bsp points at the end of the register frame so we
 	 subtract the size of frame from it to get beginning of frame.  */
@@ -1043,8 +1063,12 @@ ia64_pseudo_register_read (struct gdbarc
       ULONGEST cfm;
       ULONGEST prN_val;
       CORE_ADDR reg;
-      regcache_cooked_read_unsigned (regcache, IA64_PR_REGNUM, &pr);
-      regcache_cooked_read_unsigned (regcache, IA64_CFM_REGNUM, &cfm);
+      status = regcache_cooked_read_unsigned (regcache, IA64_PR_REGNUM, &pr);
+      if (status != REG_VALID)
+	return status;
+      status = regcache_cooked_read_unsigned (regcache, IA64_CFM_REGNUM, &cfm);
+      if (status != REG_VALID)
+	return status;
 
       if (VP16_REGNUM <= regnum && regnum <= VP63_REGNUM)
 	{
@@ -1062,6 +1086,8 @@ ia64_pseudo_register_read (struct gdbarc
     }
   else
     memset (buf, 0, register_size (gdbarch, regnum));
+
+  return REG_VALID;
 }
 
 static void
@@ -1132,7 +1158,8 @@ ia64_pseudo_register_write (struct gdbar
 	     collection from the computed address.  */
 	  if (nat_addr >= bsp)
 	    {
-	      regcache_cooked_read_unsigned (regcache, IA64_RNAT_REGNUM,
+	      regcache_cooked_read_unsigned (regcache,
+					     IA64_RNAT_REGNUM,
 					     &nat_collection);
 	      if (natN_val)
 		nat_collection |= natN_mask;
Index: src/gdb/sh-tdep.c
===================================================================
--- src.orig/gdb/sh-tdep.c	2011-02-21 20:30:32.149344005 +0000
+++ src/gdb/sh-tdep.c	2011-02-21 21:09:45.489344004 +0000
@@ -2300,43 +2300,68 @@ dr_reg_base_num (struct gdbarch *gdbarch
   return fp_regnum;
 }
 
-static void
+/* Concatenate PORTIONS contiguous raw registers starting at
+   BASE_REGNUM into BUFFER.  */
+
+static enum register_status
+pseudo_register_read_portions (struct gdbarch *gdbarch,
+			       struct regcache *regcache,
+			       int portions,
+			       int base_regnum, gdb_byte *buffer)
+{
+  int portion;
+
+  for (portion = 0; portion < portions; portion++)
+    {
+      enum register_status status;
+      gdb_byte *b;
+
+      b = buffer + register_size (gdbarch, base_regnum) * portion;
+      status = regcache_raw_read (regcache, base_regnum + portion, b);
+      if (status != REG_VALID)
+	return status;
+    }
+
+  return REG_VALID;
+}
+
+static enum register_status
 sh_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
 			 int reg_nr, gdb_byte *buffer)
 {
-  int base_regnum, portion;
+  int base_regnum;
   char temp_buffer[MAX_REGISTER_SIZE];
+  enum register_status status;
 
   if (reg_nr == PSEUDO_BANK_REGNUM)
-    regcache_raw_read (regcache, BANK_REGNUM, buffer);
-  else
-  if (reg_nr >= DR0_REGNUM && reg_nr <= DR_LAST_REGNUM)
+    return regcache_raw_read (regcache, BANK_REGNUM, buffer);
+  else if (reg_nr >= DR0_REGNUM && reg_nr <= DR_LAST_REGNUM)
     {
       base_regnum = dr_reg_base_num (gdbarch, reg_nr);
 
       /* Build the value in the provided buffer.  */
       /* Read the real regs for which this one is an alias.  */
-      for (portion = 0; portion < 2; portion++)
-	regcache_raw_read (regcache, base_regnum + portion,
-			   (temp_buffer
-			    + register_size (gdbarch,
-					     base_regnum) * portion));
-      /* We must pay attention to the endiannes.  */
-      sh_register_convert_to_virtual (reg_nr,
-				      register_type (gdbarch, reg_nr),
-				      temp_buffer, buffer);
+      status = pseudo_register_read_portions (gdbarch, regcache,
+					      2, base_regnum, temp_buffer);
+      if (status == REG_VALID)
+	{
+	  /* We must pay attention to the endiannes. */
+	  sh_register_convert_to_virtual (reg_nr,
+					  register_type (gdbarch, reg_nr),
+					  temp_buffer, buffer);
+	}
+      return status;
     }
   else if (reg_nr >= FV0_REGNUM && reg_nr <= FV_LAST_REGNUM)
     {
       base_regnum = fv_reg_base_num (gdbarch, reg_nr);
 
       /* Read the real regs for which this one is an alias.  */
-      for (portion = 0; portion < 4; portion++)
-	regcache_raw_read (regcache, base_regnum + portion,
-			   ((char *) buffer
-			    + register_size (gdbarch,
-					     base_regnum) * portion));
+      return pseudo_register_read_portions (gdbarch, regcache,
+					    4, base_regnum, buffer);
     }
+  else
+    gdb_assert_not_reached ("invalid pseudo register number");
 }
 
 static void
Index: src/gdb/sparc-tdep.c
===================================================================
--- src.orig/gdb/sparc-tdep.c	2011-02-21 20:30:32.149344005 +0000
+++ src/gdb/sparc-tdep.c	2011-02-21 21:09:45.499344005 +0000
@@ -373,16 +373,20 @@ sparc32_register_type (struct gdbarch *g
   return builtin_type (gdbarch)->builtin_int32;
 }
 
-static void
+static enum register_status
 sparc32_pseudo_register_read (struct gdbarch *gdbarch,
 			      struct regcache *regcache,
 			      int regnum, gdb_byte *buf)
 {
+  enum register_status status;
+
   gdb_assert (regnum >= SPARC32_D0_REGNUM && regnum <= SPARC32_D30_REGNUM);
 
   regnum = SPARC_F0_REGNUM + 2 * (regnum - SPARC32_D0_REGNUM);
-  regcache_raw_read (regcache, regnum, buf);
-  regcache_raw_read (regcache, regnum + 1, buf + 4);
+  status = regcache_raw_read (regcache, regnum, buf);
+  if (status == REG_VALID)
+    status = regcache_raw_read (regcache, regnum + 1, buf + 4);
+  return status;
 }
 
 static void
Index: src/gdb/sparc64-tdep.c
===================================================================
--- src.orig/gdb/sparc64-tdep.c	2011-02-21 20:30:32.149344005 +0000
+++ src/gdb/sparc64-tdep.c	2011-02-21 21:09:45.499344005 +0000
@@ -320,38 +320,52 @@ sparc64_register_type (struct gdbarch *g
   internal_error (__FILE__, __LINE__, _("invalid regnum"));
 }
 
-static void
+static enum register_status
 sparc64_pseudo_register_read (struct gdbarch *gdbarch,
 			      struct regcache *regcache,
 			      int regnum, gdb_byte *buf)
 {
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+  enum register_status status;
+
   gdb_assert (regnum >= SPARC64_NUM_REGS);
 
   if (regnum >= SPARC64_D0_REGNUM && regnum <= SPARC64_D30_REGNUM)
     {
       regnum = SPARC_F0_REGNUM + 2 * (regnum - SPARC64_D0_REGNUM);
-      regcache_raw_read (regcache, regnum, buf);
-      regcache_raw_read (regcache, regnum + 1, buf + 4);
+      status = regcache_raw_read (regcache, regnum, buf);
+      if (status == REG_VALID)
+	status = regcache_raw_read (regcache, regnum + 1, buf + 4);
+      return status;
     }
   else if (regnum >= SPARC64_D32_REGNUM && regnum <= SPARC64_D62_REGNUM)
     {
       regnum = SPARC64_F32_REGNUM + (regnum - SPARC64_D32_REGNUM);
-      regcache_raw_read (regcache, regnum, buf);
+      return regcache_raw_read (regcache, regnum, buf);
     }
   else if (regnum >= SPARC64_Q0_REGNUM && regnum <= SPARC64_Q28_REGNUM)
     {
       regnum = SPARC_F0_REGNUM + 4 * (regnum - SPARC64_Q0_REGNUM);
-      regcache_raw_read (regcache, regnum, buf);
-      regcache_raw_read (regcache, regnum + 1, buf + 4);
-      regcache_raw_read (regcache, regnum + 2, buf + 8);
-      regcache_raw_read (regcache, regnum + 3, buf + 12);
+
+      status = regcache_raw_read (regcache, regnum, buf);
+      if (status == REG_VALID)
+	status = regcache_raw_read (regcache, regnum + 1, buf + 4);
+      if (status == REG_VALID)
+	status = regcache_raw_read (regcache, regnum + 2, buf + 8);
+      if (status == REG_VALID)
+	status = regcache_raw_read (regcache, regnum + 3, buf + 12);
+
+      return status;
     }
   else if (regnum >= SPARC64_Q32_REGNUM && regnum <= SPARC64_Q60_REGNUM)
     {
       regnum = SPARC64_F32_REGNUM + 2 * (regnum - SPARC64_Q32_REGNUM);
-      regcache_raw_read (regcache, regnum, buf);
-      regcache_raw_read (regcache, regnum + 1, buf + 8);
+
+      status = regcache_raw_read (regcache, regnum, buf);
+      if (status == REG_VALID)
+	status = regcache_raw_read (regcache, regnum + 1, buf + 8);
+
+      return status;
     }
   else if (regnum == SPARC64_CWP_REGNUM
 	   || regnum == SPARC64_PSTATE_REGNUM
@@ -360,7 +374,10 @@ sparc64_pseudo_register_read (struct gdb
     {
       ULONGEST state;
 
-      regcache_raw_read_unsigned (regcache, SPARC64_STATE_REGNUM, &state);
+      status = regcache_raw_read_unsigned (regcache, SPARC64_STATE_REGNUM, &state);
+      if (status != REG_VALID)
+	return status;
+
       switch (regnum)
 	{
 	case SPARC64_CWP_REGNUM:
@@ -378,6 +395,8 @@ sparc64_pseudo_register_read (struct gdb
 	}
       store_unsigned_integer (buf, 8, byte_order, state);
     }
+
+  return REG_VALID;
 }
 
 static void
Index: src/gdb/spu-tdep.c
===================================================================
--- src.orig/gdb/spu-tdep.c	2011-02-21 20:30:32.149344005 +0000
+++ src/gdb/spu-tdep.c	2011-02-21 21:09:45.499344005 +0000
@@ -183,61 +183,66 @@ spu_register_type (struct gdbarch *gdbar
 
 /* Pseudo registers for preferred slots - stack pointer.  */
 
-static void
+static enum register_status
 spu_pseudo_register_read_spu (struct regcache *regcache, const char *regname,
 			      gdb_byte *buf)
 {
   struct gdbarch *gdbarch = get_regcache_arch (regcache);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+  enum register_status status;
   gdb_byte reg[32];
   char annex[32];
   ULONGEST id;
 
-  regcache_raw_read_unsigned (regcache, SPU_ID_REGNUM, &id);
+  status = regcache_raw_read_unsigned (regcache, SPU_ID_REGNUM, &id);
+  if (status != REG_VALID)
+    return status;
   xsnprintf (annex, sizeof annex, "%d/%s", (int) id, regname);
   memset (reg, 0, sizeof reg);
   target_read (&current_target, TARGET_OBJECT_SPU, annex,
 	       reg, 0, sizeof reg);
 
   store_unsigned_integer (buf, 4, byte_order, strtoulst (reg, NULL, 16));
+  return REG_VALID;
 }
 
-static void
+static enum register_status
 spu_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
                           int regnum, gdb_byte *buf)
 {
   gdb_byte reg[16];
   char annex[32];
   ULONGEST id;
+  enum register_status status;
 
   switch (regnum)
     {
     case SPU_SP_REGNUM:
-      regcache_raw_read (regcache, SPU_RAW_SP_REGNUM, reg);
+      status = regcache_raw_read (regcache, SPU_RAW_SP_REGNUM, reg);
+      if (status != REG_VALID)
+	return status;
       memcpy (buf, reg, 4);
-      break;
+      return status;
 
     case SPU_FPSCR_REGNUM:
-      regcache_raw_read_unsigned (regcache, SPU_ID_REGNUM, &id);
+      status = regcache_raw_read_unsigned (regcache, SPU_ID_REGNUM, &id);
+      if (status != REG_VALID)
+	return status;
       xsnprintf (annex, sizeof annex, "%d/fpcr", (int) id);
       target_read (&current_target, TARGET_OBJECT_SPU, annex, buf, 0, 16);
-      break;
+      return status;
 
     case SPU_SRR0_REGNUM:
-      spu_pseudo_register_read_spu (regcache, "srr0", buf);
-      break;
+      return spu_pseudo_register_read_spu (regcache, "srr0", buf);
 
     case SPU_LSLR_REGNUM:
-      spu_pseudo_register_read_spu (regcache, "lslr", buf);
-      break;
+      return spu_pseudo_register_read_spu (regcache, "lslr", buf);
 
     case SPU_DECR_REGNUM:
-      spu_pseudo_register_read_spu (regcache, "decr", buf);
-      break;
+      return spu_pseudo_register_read_spu (regcache, "decr", buf);
 
     case SPU_DECR_STATUS_REGNUM:
-      spu_pseudo_register_read_spu (regcache, "decr_status", buf);
-      break;
+      return spu_pseudo_register_read_spu (regcache, "decr_status", buf);
 
     default:
       internal_error (__FILE__, __LINE__, _("invalid regnum"));
Index: src/gdb/xtensa-tdep.c
===================================================================
--- src.orig/gdb/xtensa-tdep.c	2011-02-21 20:30:32.149344005 +0000
+++ src/gdb/xtensa-tdep.c	2011-02-21 21:09:45.499344005 +0000
@@ -411,7 +411,7 @@ xtensa_register_write_masked (struct reg
 /* Read a tie state or mapped registers.  Read the masked areas
    of the registers and assemble them into a single value.  */
 
-static void
+static enum register_status
 xtensa_register_read_masked (struct regcache *regcache,
 			     xtensa_register_t *reg, gdb_byte *buffer)
 {
@@ -437,8 +437,12 @@ xtensa_register_read_masked (struct regc
       int r = mask->mask[i].reg_num;
       if (r >= 0)
 	{
+	  enum register_status status;
 	  ULONGEST val;
-	  regcache_cooked_read_unsigned (regcache, r, &val);
+
+	  status = regcache_cooked_read_unsigned (regcache, r, &val);
+	  if (status != REG_VALID)
+	    return status;
 	  regval = (unsigned int) val;
 	}
       else
@@ -493,12 +497,14 @@ xtensa_register_read_masked (struct regc
 	buffer[i] = mem & 0xff;
 	mem >>= 8;
       }
+
+  return REG_VALID;
 }
 
 
 /* Read pseudo registers.  */
 
-static void
+static enum register_status
 xtensa_pseudo_register_read (struct gdbarch *gdbarch,
 			     struct regcache *regcache,
 			     int regnum,
@@ -519,16 +525,20 @@ xtensa_pseudo_register_read (struct gdba
       && (regnum <= gdbarch_tdep (gdbarch)->a0_base + 15))
     {
       gdb_byte *buf = (gdb_byte *) alloca (MAX_REGISTER_SIZE);
+      enum register_status status;
 
-      regcache_raw_read (regcache, gdbarch_tdep (gdbarch)->wb_regnum, buf);
+      status = regcache_raw_read (regcache,
+				  gdbarch_tdep (gdbarch)->wb_regnum,
+				  buf);
+      if (status != REG_VALID)
+	return status;
       regnum = arreg_number (gdbarch, regnum,
 			     extract_unsigned_integer (buf, 4, byte_order));
     }
 
   /* We can always read non-pseudo registers.  */
   if (regnum >= 0 && regnum < gdbarch_num_regs (gdbarch))
-    regcache_raw_read (regcache, regnum, buffer);
-
+    return regcache_raw_read (regcache, regnum, buffer);
 
   /* We have to find out how to deal with priveleged registers.
      Let's treat them as pseudo-registers, but we cannot read/write them.  */
@@ -539,6 +549,7 @@ xtensa_pseudo_register_read (struct gdba
       buffer[1] = (gdb_byte)0;
       buffer[2] = (gdb_byte)0;
       buffer[3] = (gdb_byte)0;
+      return REG_VALID;
     }
   /* Pseudo registers.  */
   else if (regnum >= 0
@@ -556,7 +567,7 @@ xtensa_pseudo_register_read (struct gdba
 	    {
 	      warning (_("cannot read register %s"),
 		       xtensa_register_name (gdbarch, regnum));
-	      return;
+	      return REG_VALID;
 	    }
 	}
 
@@ -567,26 +578,23 @@ xtensa_pseudo_register_read (struct gdba
 	  if (flags & xtTargetFlagsUseFetchStore)
 	    {
 	      warning (_("cannot read register"));
-	      return;
+	      return REG_VALID;
 	    }
 
 	  /* On some targets (esp. simulators), we can always read the reg.  */
 	  else if ((flags & xtTargetFlagsNonVisibleRegs) == 0)
 	    {
 	      warning (_("cannot read register"));
-	      return;
+	      return REG_VALID;
 	    }
 	}
 
       /* We can always read mapped registers.  */
       else if (type == xtRegisterTypeMapped || type == xtRegisterTypeTieState)
-        {
-	  xtensa_register_read_masked (regcache, reg, buffer);
-	  return;
-	}
+	return xtensa_register_read_masked (regcache, reg, buffer);
 
       /* Assume that we can read the register.  */
-      regcache_raw_read (regcache, regnum, buffer);
+      return regcache_raw_read (regcache, regnum, buffer);
     }
   else
     internal_error (__FILE__, __LINE__,
Index: src/gdb/bfin-tdep.c
===================================================================
--- src.orig/gdb/bfin-tdep.c	2011-02-21 20:30:32.149344005 +0000
+++ src/gdb/bfin-tdep.c	2011-02-21 21:09:45.499344005 +0000
@@ -687,20 +687,25 @@ bfin_register_name (struct gdbarch *gdba
   return bfin_register_name_strings[i];
 }
 
-static void
+static enum register_status
 bfin_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
 			   int regnum, gdb_byte *buffer)
 {
   gdb_byte *buf = (gdb_byte *) alloca (MAX_REGISTER_SIZE);
+  enum register_status status;
 
   if (regnum != BFIN_CC_REGNUM)
     internal_error (__FILE__, __LINE__,
 		    _("invalid register number %d"), regnum);
 
   /* Extract the CC bit from the ASTAT register.  */
-  regcache_raw_read (regcache, BFIN_ASTAT_REGNUM, buf);
-  buffer[1] = buffer[2] = buffer[3] = 0;
-  buffer[0] = !!(buf[0] & ASTAT_CC);
+  status = regcache_raw_read (regcache, BFIN_ASTAT_REGNUM, buf);
+  if (status == REG_VALID)
+    {
+      buffer[1] = buffer[2] = buffer[3] = 0;
+      buffer[0] = !!(buf[0] & ASTAT_CC);
+    }
+  return status;
 }
 
 static void
@@ -708,15 +713,19 @@ bfin_pseudo_register_write (struct gdbar
 			    int regnum, const gdb_byte *buffer)
 {
   gdb_byte *buf = (gdb_byte *) alloca (MAX_REGISTER_SIZE);
+  enum register_status status;
 
   if (regnum != BFIN_CC_REGNUM)
     internal_error (__FILE__, __LINE__,
 		    _("invalid register number %d"), regnum);
 
   /* Overlay the CC bit in the ASTAT register.  */
-  regcache_raw_read (regcache, BFIN_ASTAT_REGNUM, buf);
-  buf[0] = (buf[0] & ~ASTAT_CC) | ((buffer[0] & 1) << ASTAT_CC_POS);
-  regcache_raw_write (regcache, BFIN_ASTAT_REGNUM, buf);
+  status = regcache_raw_read (regcache, BFIN_ASTAT_REGNUM, buf);
+  if (status == REG_VALID)
+    {
+      buf[0] = (buf[0] & ~ASTAT_CC) | ((buffer[0] & 1) << ASTAT_CC_POS);
+      regcache_raw_write (regcache, BFIN_ASTAT_REGNUM, buf);
+    }
 }
 
 static CORE_ADDR


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]