summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPedro Alves <palves@redhat.com>2011-03-18 18:38:44 +0000
committerPedro Alves <palves@redhat.com>2011-03-18 18:38:44 +0000
commit05d1431c1e0a4ecf30462109f5fb9876d78b7b4a (patch)
tree76012c85051dd07166944e314a83502d47b1ba1a
parent5548b4ce8ccff9f4a198fdfbcc47a83baa9ed876 (diff)
downloadbinutils-gdb-05d1431c1e0a4ecf30462109f5fb9876d78b7b4a.tar.gz
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: Include exceptions.h (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. (regcache_read_pc): Throw NOT_AVAILABLE_ERROR if the register is unavailable. (regcache_dump): Handle unavailable cooked registers. * 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.
-rw-r--r--gdb/ChangeLog106
-rw-r--r--gdb/amd64-tdep.c27
-rw-r--r--gdb/arm-tdep.c31
-rw-r--r--gdb/avr-tdep.c9
-rw-r--r--gdb/bfin-tdep.c13
-rw-r--r--gdb/frame.c7
-rw-r--r--gdb/frv-tdep.c29
-rw-r--r--gdb/gdbarch.c4
-rw-r--r--gdb/gdbarch.h4
-rwxr-xr-xgdb/gdbarch.sh2
-rw-r--r--gdb/h8300-tdep.c8
-rw-r--r--gdb/hppa-tdep.c19
-rw-r--r--gdb/i386-tdep.c33
-rw-r--r--gdb/i386-tdep.h7
-rw-r--r--gdb/ia64-tdep.c51
-rw-r--r--gdb/m32c-tdep.c96
-rw-r--r--gdb/m68hc11-tdep.c11
-rw-r--r--gdb/mep-tdep.c27
-rw-r--r--gdb/mips-tdep.c14
-rw-r--r--gdb/mt-tdep.c29
-rw-r--r--gdb/regcache.c183
-rw-r--r--gdb/regcache.h62
-rw-r--r--gdb/rs6000-tdep.c119
-rw-r--r--gdb/s390-tdep.c54
-rw-r--r--gdb/sh-tdep.c63
-rw-r--r--gdb/sh64-tdep.c108
-rw-r--r--gdb/sparc-tdep.c10
-rw-r--r--gdb/sparc64-tdep.c41
-rw-r--r--gdb/spu-tdep.c35
-rw-r--r--gdb/xtensa-tdep.c36
30 files changed, 842 insertions, 396 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 4e4da653d58..c9469da0df6 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,109 @@
+2011-03-18 Pedro Alves <pedro@codesourcery.com>
+
+ * 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: Include exceptions.h
+ (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.
+ (regcache_read_pc): Throw NOT_AVAILABLE_ERROR if the register is
+ unavailable.
+ (regcache_dump): Handle unavailable cooked registers.
+ * 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.
+
2011-03-18 Pierre Muller <muller@ics.u-strasbg.fr>
* python/py-value.c (valpy_getitem): Fix formatting of error function
diff --git a/gdb/amd64-tdep.c b/gdb/amd64-tdep.c
index fdb0c213f25..54b17236db9 100644
--- a/gdb/amd64-tdep.c
+++ b/gdb/amd64-tdep.c
@@ -275,13 +275,14 @@ amd64_pseudo_register_name (struct gdbarch *gdbarch, int regnum)
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 gdbarch *gdbarch,
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
diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
index 6e5f2ab16a8..0020b47c0d2 100644
--- a/gdb/arm-tdep.c
+++ b/gdb/arm-tdep.c
@@ -213,9 +213,9 @@ static void convert_from_extended (const struct floatformat *, const void *,
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);
@@ -7899,13 +7899,14 @@ arm_write_pc (struct regcache *regcache, CORE_ADDR pc)
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,
@@ -7917,15 +7918,21 @@ arm_neon_quad_read (struct gdbarch *gdbarch, struct regcache *regcache,
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)
{
@@ -7939,9 +7946,11 @@ arm_pseudo_read (struct gdbarch *gdbarch, struct regcache *regcache,
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);
@@ -7955,8 +7964,10 @@ arm_pseudo_read (struct gdbarch *gdbarch, struct regcache *regcache,
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;
}
}
diff --git a/gdb/avr-tdep.c b/gdb/avr-tdep.c
index f9fc5e6acf9..31dd7df4ab5 100644
--- a/gdb/avr-tdep.c
+++ b/gdb/avr-tdep.c
@@ -354,19 +354,22 @@ avr_write_pc (struct regcache *regcache, CORE_ADDR val)
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"));
}
diff --git a/gdb/bfin-tdep.c b/gdb/bfin-tdep.c
index 7de0b1be8bd..8c0cb5a325b 100644
--- a/gdb/bfin-tdep.c
+++ b/gdb/bfin-tdep.c
@@ -689,20 +689,25 @@ bfin_register_name (struct gdbarch *gdbarch, int i)
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
diff --git a/gdb/frame.c b/gdb/frame.c
index 1fe6256ff1a..3bc211ebbb9 100644
--- a/gdb/frame.c
+++ b/gdb/frame.c
@@ -687,10 +687,13 @@ get_frame_func (struct frame_info *this_frame)
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 *
diff --git a/gdb/frv-tdep.c b/gdb/frv-tdep.c
index a5a9a0ba9a4..66c25a854f2 100644
--- a/gdb/frv-tdep.c
+++ b/gdb/frv-tdep.c
@@ -300,14 +300,17 @@ frv_register_type (struct gdbarch *gdbarch, int reg)
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 *gdbarch, struct regcache *regcache,
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
diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c
index 978d93cde96..8b97f20413a 100644
--- a/gdb/gdbarch.c
+++ b/gdb/gdbarch.c
@@ -1682,14 +1682,14 @@ gdbarch_pseudo_register_read_p (struct gdbarch *gdbarch)
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
diff --git a/gdb/gdbarch.h b/gdb/gdbarch.h
index 863d3955b8f..7284f76e92c 100644
--- a/gdb/gdbarch.h
+++ b/gdb/gdbarch.h
@@ -212,8 +212,8 @@ extern void set_gdbarch_virtual_frame_pointer (struct gdbarch *gdbarch, gdbarch_
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);
diff --git a/gdb/gdbarch.sh b/gdb/gdbarch.sh
index d66626a8b2d..2f987ae1150 100755
--- a/gdb/gdbarch.sh
+++ b/gdb/gdbarch.sh
@@ -417,7 +417,7 @@ F:void:write_pc:struct regcache *regcache, CORE_ADDR val:regcache, val
# 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
diff --git a/gdb/h8300-tdep.c b/gdb/h8300-tdep.c
index cfcd9740e63..0b11df36d52 100644
--- a/gdb/h8300-tdep.c
+++ b/gdb/h8300-tdep.c
@@ -1149,17 +1149,17 @@ h8300_register_type (struct gdbarch *gdbarch, int regno)
}
}
-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
diff --git a/gdb/hppa-tdep.c b/gdb/hppa-tdep.c
index 334870fe507..df21faddcd3 100644
--- a/gdb/hppa-tdep.c
+++ b/gdb/hppa-tdep.c
@@ -2665,17 +2665,22 @@ hppa_fetch_pointer_argument (struct frame_info *frame, int argi,
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
diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c
index eab8e44b0c7..6330ceb7d2f 100644
--- a/gdb/i386-tdep.c
+++ b/gdb/i386-tdep.c
@@ -2541,18 +2541,21 @@ i386_mmx_regnum_to_fp_regnum (struct regcache *regcache, int regnum)
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
@@ -2564,14 +2567,18 @@ i386_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
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))
@@ -2579,7 +2586,9 @@ i386_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
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))
@@ -2591,7 +2600,9 @@ i386_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
/* 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
@@ -2600,6 +2611,8 @@ i386_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
else
internal_error (__FILE__, __LINE__, _("invalid regnum"));
}
+
+ return REG_VALID;
}
void
diff --git a/gdb/i386-tdep.h b/gdb/i386-tdep.h
index bb2f2c73884..7fc719c74c0 100644
--- a/gdb/i386-tdep.h
+++ b/gdb/i386-tdep.h
@@ -311,9 +311,10 @@ extern int i386_ymm_regnum_p (struct gdbarch *gdbarch, int regnum);
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);
diff --git a/gdb/ia64-tdep.c b/gdb/ia64-tdep.c
index ea6918c1021..cbd8514acc5 100644
--- a/gdb/ia64-tdep.c
+++ b/gdb/ia64-tdep.c
@@ -933,11 +933,12 @@ rse_address_add(CORE_ADDR addr, int nslots)
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 gdbarch *gdbarch, struct regcache *regcache,
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 gdbarch *gdbarch, struct regcache *regcache,
{
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 gdbarch *gdbarch, struct regcache *regcache,
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 gdbarch *gdbarch, struct regcache *regcache,
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 gdbarch *gdbarch, struct regcache *regcache,
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 gdbarch *gdbarch, struct regcache *regcache,
}
else
memset (buf, 0, register_size (gdbarch, regnum));
+
+ return REG_VALID;
}
static void
@@ -1132,7 +1158,8 @@ ia64_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
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;
diff --git a/gdb/m32c-tdep.c b/gdb/m32c-tdep.c
index 3484b00c887..454a4b681c2 100644
--- a/gdb/m32c-tdep.c
+++ b/gdb/m32c-tdep.c
@@ -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_read, m32c_r3r2r1r0_write;
/* 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 *reg, struct regcache *cache)
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, struct regcache *cache, void *buf)
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, int *offset_p, int *len_p)
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, struct regcache *cache, void *buf)
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, struct regcache *cache, void *buf)
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 *reg, struct regcache *cache, void *buf)
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 gdbarch *arch,
gdb_assert (arch == tdep->regs[cookednum].arch);
reg = &tdep->regs[cookednum];
- reg->read (reg, cache, buf);
+ return reg->read (reg, cache, buf);
}
diff --git a/gdb/m68hc11-tdep.c b/gdb/m68hc11-tdep.c
index 005a01f5474..ced6eabb520 100644
--- a/gdb/m68hc11-tdep.c
+++ b/gdb/m68hc11-tdep.c
@@ -279,7 +279,7 @@ m68hc11_which_soft_register (CORE_ADDR addr)
/* 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 gdbarch *gdbarch,
{
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 gdbarch *gdbarch,
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 gdbarch *gdbarch,
{
memset (buf, 0, 2);
}
+
+ return REG_VALID;
}
/* Store a pseudo register. Translate the register store
diff --git a/gdb/mep-tdep.c b/gdb/mep-tdep.c
index b8759bc1af4..dd5a4a541b3 100644
--- a/gdb/mep-tdep.c
+++ b/gdb/mep-tdep.c
@@ -1133,12 +1133,13 @@ mep_write_pc (struct regcache *regcache, CORE_ADDR pc)
}
-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 *gdbarch,
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 *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");
}
diff --git a/gdb/mips-tdep.c b/gdb/mips-tdep.c
index ef4cf9b14be..04ce30a29ba 100644
--- a/gdb/mips-tdep.c
+++ b/gdb/mips-tdep.c
@@ -564,7 +564,7 @@ mips_tdesc_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
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 gdbarch *gdbarch, struct regcache *regcache,
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
diff --git a/gdb/mt-tdep.c b/gdb/mt-tdep.c
index f67ddfa719f..9b0971f7626 100644
--- a/gdb/mt-tdep.c
+++ b/gdb/mt-tdep.c
@@ -524,9 +524,9 @@ mt_select_coprocessor (struct gdbarch *gdbarch,
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 *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;
}
diff --git a/gdb/regcache.c b/gdb/regcache.c
index 286f1d125da..b984bc1400b 100644
--- a/gdb/regcache.c
+++ b/gdb/regcache.c
@@ -29,6 +29,7 @@
#include "gdb_string.h"
#include "gdbcmd.h" /* For maintenanceprintlist. */
#include "observer.h"
+#include "exceptions.h"
/*
* DATA STRUCTURE
@@ -312,14 +313,19 @@ regcache_save (struct regcache *dst, regcache_cooked_read_ftype *cooked_read,
{
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 +358,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 +577,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 +606,53 @@ regcache_raw_read (struct regcache *regcache, int regnum, gdb_byte *buf)
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 +682,71 @@ regcache_raw_write_unsigned (struct regcache *regcache, int regnum,
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 +832,12 @@ typedef void (regcache_read_ftype) (struct regcache *regcache, int regnum,
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 +848,18 @@ regcache_xfer_part (struct regcache *regcache, int regnum,
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 +872,19 @@ regcache_xfer_part (struct regcache *regcache, int regnum,
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 +898,15 @@ regcache_raw_write_part (struct regcache *regcache, int regnum,
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
@@ -943,9 +983,11 @@ regcache_read_pc (struct regcache *regcache)
{
ULONGEST raw_val;
- regcache_cooked_read_unsigned (regcache,
- gdbarch_pc_regnum (gdbarch),
- &raw_val);
+ if (regcache_cooked_read_unsigned (regcache,
+ gdbarch_pc_regnum (gdbarch),
+ &raw_val) == REG_UNAVAILABLE)
+ throw_error (NOT_AVAILABLE_ERROR, _("PC register is not available"));
+
pc_val = gdbarch_addr_bits_remove (gdbarch, raw_val);
}
else
@@ -1164,13 +1206,20 @@ regcache_dump (struct regcache *regcache, struct ui_file *file,
fprintf_unfiltered (file, "Cooked value");
else
{
- /* FIXME: no way for cooked reads to signal unavailable
- yet. */
- regcache_cooked_read (regcache, regnum, buf);
- fprintf_unfiltered (file, "0x");
- dump_endian_bytes (file,
- gdbarch_byte_order (gdbarch), buf,
- regcache->descr->sizeof_register[regnum]);
+ enum register_status status;
+
+ status = regcache_cooked_read (regcache, regnum, buf);
+ if (status == REG_UNKNOWN)
+ fprintf_unfiltered (file, "<invalid>");
+ else if (status == REG_UNAVAILABLE)
+ fprintf_unfiltered (file, "<unavailable>");
+ else
+ {
+ fprintf_unfiltered (file, "0x");
+ dump_endian_bytes (file,
+ gdbarch_byte_order (gdbarch), buf,
+ regcache->descr->sizeof_register[regnum]);
+ }
}
}
diff --git a/gdb/regcache.h b/gdb/regcache.h
index 7ae585ab2c4..3708c86d640 100644
--- a/gdb/regcache.h
+++ b/gdb/regcache.h
@@ -64,49 +64,53 @@ enum register_status regcache_register_status (const struct regcache *regcache,
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. */
+/* Partial transfer of raw registers. These perform read, modify,
+ write style operations. The read variant returns the status of the
+ register. */
-void regcache_raw_read_part (struct regcache *regcache, int regnum,
- int offset, int len, gdb_byte *buf);
+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_unsigned (struct regcache *regcache,
/* 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 *gdbarch, int regnum);
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,
diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c
index 6ac3e8dc9f3..b8c87fb8b82 100644
--- a/gdb/rs6000-tdep.c
+++ b/gdb/rs6000-tdep.c
@@ -2536,6 +2536,11 @@ rs6000_value_to_register (struct frame_info *frame,
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_info *frame,
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) (struct regcache *regcache,
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 gdbarch *gdbarch, struct regcache *regcache,
}
/* 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 gdbarch *gdbarch, struct regcache *regcache,
}
/* 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 gdbarch *gdbarch, struct regcache *regcache,
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 gdbarch *gdbarch, struct regcache *regcache,
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 gdbarch *gdbarch,
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: "
diff --git a/gdb/s390-tdep.c b/gdb/s390-tdep.c
index 85e4c130001..d74bbf05814 100644
--- a/gdb/s390-tdep.c
+++ b/gdb/s390-tdep.c
@@ -216,7 +216,7 @@ s390_pseudo_register_type (struct gdbarch *gdbarch, int regnum)
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 gdbarch *gdbarch, struct regcache *regcache,
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"));
diff --git a/gdb/sh-tdep.c b/gdb/sh-tdep.c
index 1b9fd905d76..49ef8c64a0f 100644
--- a/gdb/sh-tdep.c
+++ b/gdb/sh-tdep.c
@@ -2300,43 +2300,68 @@ dr_reg_base_num (struct gdbarch *gdbarch, int dr_regnum)
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
diff --git a/gdb/sh64-tdep.c b/gdb/sh64-tdep.c
index 06a7762c391..dca560a1c56 100644
--- a/gdb/sh64-tdep.c
+++ b/gdb/sh64-tdep.c
@@ -1619,15 +1619,40 @@ sh64_register_convert_to_raw (struct gdbarch *gdbarch, struct type *type,
"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 gdbarch *gdbarch, struct regcache *regcache,
/* 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 gdbarch *gdbarch, struct regcache *regcache,
/* 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 gdbarch *gdbarch, struct regcache *regcache,
/* 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 gdbarch *gdbarch, struct regcache *regcache,
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 gdbarch *gdbarch, struct regcache *regcache,
/* 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 gdbarch *gdbarch, struct regcache *regcache,
/* 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 gdbarch *gdbarch, struct regcache *regcache,
/* 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 gdbarch *gdbarch, struct regcache *regcache,
*/
/* *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 gdbarch *gdbarch, struct regcache *regcache,
/* 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 gdbarch *gdbarch, struct regcache *regcache,
/* 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
diff --git a/gdb/sparc-tdep.c b/gdb/sparc-tdep.c
index b71a40f3a46..90817c9caf6 100644
--- a/gdb/sparc-tdep.c
+++ b/gdb/sparc-tdep.c
@@ -373,16 +373,20 @@ sparc32_register_type (struct gdbarch *gdbarch, int regnum)
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
diff --git a/gdb/sparc64-tdep.c b/gdb/sparc64-tdep.c
index cd442257876..4b42f01556b 100644
--- a/gdb/sparc64-tdep.c
+++ b/gdb/sparc64-tdep.c
@@ -320,38 +320,52 @@ sparc64_register_type (struct gdbarch *gdbarch, int regnum)
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 gdbarch *gdbarch,
{
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 gdbarch *gdbarch,
}
store_unsigned_integer (buf, 8, byte_order, state);
}
+
+ return REG_VALID;
}
static void
diff --git a/gdb/spu-tdep.c b/gdb/spu-tdep.c
index b0709935082..7f0cd7d3dbb 100644
--- a/gdb/spu-tdep.c
+++ b/gdb/spu-tdep.c
@@ -183,61 +183,66 @@ spu_register_type (struct gdbarch *gdbarch, int reg_nr)
/* 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"));
diff --git a/gdb/xtensa-tdep.c b/gdb/xtensa-tdep.c
index 1bb97ba1730..316a8cf5194 100644
--- a/gdb/xtensa-tdep.c
+++ b/gdb/xtensa-tdep.c
@@ -453,7 +453,7 @@ xtensa_register_write_masked (struct regcache *regcache,
/* 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)
{
@@ -479,8 +479,12 @@ xtensa_register_read_masked (struct regcache *regcache,
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
@@ -535,12 +539,14 @@ xtensa_register_read_masked (struct regcache *regcache,
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,
@@ -561,16 +567,20 @@ xtensa_pseudo_register_read (struct gdbarch *gdbarch,
&& (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. */
@@ -581,6 +591,7 @@ xtensa_pseudo_register_read (struct gdbarch *gdbarch,
buffer[1] = (gdb_byte)0;
buffer[2] = (gdb_byte)0;
buffer[3] = (gdb_byte)0;
+ return REG_VALID;
}
/* Pseudo registers. */
else if (regnum >= 0
@@ -598,7 +609,7 @@ xtensa_pseudo_register_read (struct gdbarch *gdbarch,
{
warning (_("cannot read register %s"),
xtensa_register_name (gdbarch, regnum));
- return;
+ return REG_VALID;
}
}
@@ -609,26 +620,23 @@ xtensa_pseudo_register_read (struct gdbarch *gdbarch,
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__,