From 05d1431c1e0a4ecf30462109f5fb9876d78b7b4a Mon Sep 17 00:00:00 2001 From: Pedro Alves Date: Fri, 18 Mar 2011 18:38:44 +0000 Subject: [PATCH] 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. --- gdb/ChangeLog | 106 ++++++++++++++++++++++++++ gdb/amd64-tdep.c | 27 ++++--- gdb/arm-tdep.c | 31 +++++--- gdb/avr-tdep.c | 9 ++- gdb/bfin-tdep.c | 13 +++- gdb/frame.c | 7 +- gdb/frv-tdep.c | 29 ++++--- gdb/gdbarch.c | 4 +- gdb/gdbarch.h | 4 +- gdb/gdbarch.sh | 2 +- gdb/h8300-tdep.c | 8 +- gdb/hppa-tdep.c | 19 +++-- gdb/i386-tdep.c | 33 +++++--- gdb/i386-tdep.h | 7 +- gdb/ia64-tdep.c | 51 ++++++++++--- gdb/m32c-tdep.c | 96 +++++++++++++++--------- gdb/m68hc11-tdep.c | 11 ++- gdb/mep-tdep.c | 27 ++++--- gdb/mips-tdep.c | 14 ++-- gdb/mt-tdep.c | 29 ++++--- gdb/regcache.c | 183 ++++++++++++++++++++++++++++----------------- gdb/regcache.h | 62 ++++++++------- gdb/rs6000-tdep.c | 119 ++++++++++++++++++----------- gdb/s390-tdep.c | 54 ++++++++----- gdb/sh-tdep.c | 63 +++++++++++----- gdb/sh64-tdep.c | 108 ++++++++++++++++---------- gdb/sparc-tdep.c | 10 ++- gdb/sparc64-tdep.c | 41 +++++++--- gdb/spu-tdep.c | 35 +++++---- gdb/xtensa-tdep.c | 36 +++++---- 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 + + * 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 * 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, ®val); - store_signed_integer (buf, 4, byte_order, regval); + enum register_status status; + + status = regcache_raw_read_signed (regcache, rawnum, ®val); + 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, ""); + else if (status == REG_UNAVAILABLE) + fprintf_unfiltered (file, ""); + 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 (¤t_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 (¤t_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__, -- 2.30.2