summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYao Qi <yao.qi@linaro.org>2017-11-24 13:04:30 +0000
committerYao Qi <yao.qi@linaro.org>2017-11-24 13:04:30 +0000
commita63f2d2feedcfce401ae1d7d03d119bfa5e4d8bc (patch)
treeeea14e9b568e35e4768da17556431051e6945df4
parent1b30aaa56607a563fa263b9d2ee9eba89d79c1b4 (diff)
downloadbinutils-gdb-a63f2d2feedcfce401ae1d7d03d119bfa5e4d8bc.tar.gz
cooked_read test for readonly regcache
This patch adds a test to check cooked_read for readonly regcache. For raw registers, cooked_read get either REG_VALID or REG_UNKNOWN, depends on the raw register is in save_reggroup or not. For pseudo register, cooked_read get different result in different ports. gdb: 2017-11-24 Yao Qi <yao.qi@linaro.org> * regcache.c (cooked_read_test): Add more test for readonly regcache.
-rw-r--r--gdb/ChangeLog5
-rw-r--r--gdb/regcache.c76
2 files changed, 81 insertions, 0 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 9947aaa8356..aecd85b2f34 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,10 @@
2017-11-24 Yao Qi <yao.qi@linaro.org>
+ * regcache.c (cooked_read_test): Add more test for readonly
+ regcache.
+
+2017-11-24 Yao Qi <yao.qi@linaro.org>
+
* gdbarch-selftests.c (test_target_has_registers): Move it to
target.c.
(test_target_has_stack): Likewise.
diff --git a/gdb/regcache.c b/gdb/regcache.c
index c37a520b3f8..e82176b202c 100644
--- a/gdb/regcache.c
+++ b/gdb/regcache.c
@@ -1865,6 +1865,82 @@ cooked_read_test (struct gdbarch *gdbarch)
mock_target.reset ();
}
+
+ regcache readonly (regcache::readonly, readwrite);
+
+ /* GDB may go to target layer to fetch all registers and memory for
+ readonly regcache. */
+ mock_target.reset ();
+
+ for (int regnum = 0;
+ regnum < gdbarch_num_regs (gdbarch) + gdbarch_num_pseudo_regs (gdbarch);
+ regnum++)
+ {
+ if (gdbarch_bfd_arch_info (gdbarch)->arch == bfd_arch_mt)
+ {
+ /* Trigger an internal error otherwise. */
+ continue;
+ }
+
+ if (register_size (gdbarch, regnum) == 0)
+ continue;
+
+ gdb::def_vector<gdb_byte> buf (register_size (gdbarch, regnum));
+ enum register_status status = readonly.cooked_read (regnum,
+ buf.data ());
+
+ if (regnum < gdbarch_num_regs (gdbarch))
+ {
+ auto bfd_arch = gdbarch_bfd_arch_info (gdbarch)->arch;
+
+ if (bfd_arch == bfd_arch_frv || bfd_arch == bfd_arch_h8300
+ || bfd_arch == bfd_arch_m32c || bfd_arch == bfd_arch_sh
+ || bfd_arch == bfd_arch_alpha || bfd_arch == bfd_arch_v850
+ || bfd_arch == bfd_arch_msp430 || bfd_arch == bfd_arch_mep
+ || bfd_arch == bfd_arch_mips || bfd_arch == bfd_arch_v850_rh850
+ || bfd_arch == bfd_arch_tic6x || bfd_arch == bfd_arch_mn10300
+ || bfd_arch == bfd_arch_rl78 || bfd_arch == bfd_arch_score)
+ {
+ /* Raw registers. If raw registers are not in save_reggroup,
+ their status are unknown. */
+ if (gdbarch_register_reggroup_p (gdbarch, regnum, save_reggroup))
+ SELF_CHECK (status == REG_VALID);
+ else
+ SELF_CHECK (status == REG_UNKNOWN);
+ }
+ else
+ SELF_CHECK (status == REG_VALID);
+ }
+ else
+ {
+ if (gdbarch_register_reggroup_p (gdbarch, regnum, save_reggroup))
+ SELF_CHECK (status == REG_VALID);
+ else
+ {
+ /* If pseudo registers are not in save_reggroup, some of
+ them can be computed from saved raw registers, but some
+ of them are unknown. */
+ auto bfd_arch = gdbarch_bfd_arch_info (gdbarch)->arch;
+
+ if (bfd_arch == bfd_arch_frv
+ || bfd_arch == bfd_arch_m32c
+ || bfd_arch == bfd_arch_mep
+ || bfd_arch == bfd_arch_sh)
+ SELF_CHECK (status == REG_VALID || status == REG_UNKNOWN);
+ else if (bfd_arch == bfd_arch_mips
+ || bfd_arch == bfd_arch_h8300)
+ SELF_CHECK (status == REG_UNKNOWN);
+ else
+ SELF_CHECK (status == REG_VALID);
+ }
+ }
+
+ SELF_CHECK (mock_target.fetch_registers_called == 0);
+ SELF_CHECK (mock_target.store_registers_called == 0);
+ SELF_CHECK (mock_target.xfer_partial_called == 0);
+
+ mock_target.reset ();
+ }
}
} // namespace selftests