aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog19
-rw-r--r--gdb/frame.c17
-rw-r--r--gdb/frame.h8
-rw-r--r--gdb/gdbarch-selftests.c105
-rw-r--r--gdb/progspace.c12
-rw-r--r--gdb/progspace.h11
-rw-r--r--gdb/regcache.h10
7 files changed, 119 insertions, 63 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 37d86ae..726dbc7 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,22 @@
+2017-10-04 Pedro Alves <palves@redhat.com>
+
+ * frame.c (create_test_frame): Delete.
+ * frame.h (create_test_frame): Delete.
+ * gdbarch-selftests.c: Include gdbthread.h and target.h.
+ (class regcache_test): Delete.
+ (test_target_has_registers, test_target_has_stack)
+ (test_target_has_memory, test_target_prepare_to_store)
+ (test_target_store_registers): New functions.
+ (test_target_ops): New class.
+ (register_to_value_test): Error out if there's already a
+ process_stratum (or higher) target pushed. Create a fuller mock
+ environment, with mock target_ops, inferior, address space, thread
+ and inferior_ptid.
+ * progspace.c (struct address_space): Move to ...
+ * progspace.h (struct address_space): ... here.
+ * regcache.h (regcache::~regcache, regcache::raw_write)
+ [GDB_SELF_TEST]: No longer virtual.
+
2017-10-04 Simon Marchi <simon.marchi@ericsson.com>
* mi/mi-main.c (list_available_thread_groups): Reverse filter logic.
diff --git a/gdb/frame.c b/gdb/frame.c
index a74deef..afdc157 100644
--- a/gdb/frame.c
+++ b/gdb/frame.c
@@ -1716,23 +1716,6 @@ select_frame (struct frame_info *fi)
}
}
-#if GDB_SELF_TEST
-struct frame_info *
-create_test_frame (struct regcache *regcache)
-{
- struct frame_info *this_frame = XCNEW (struct frame_info);
-
- sentinel_frame = create_sentinel_frame (NULL, regcache);
- sentinel_frame->prev = this_frame;
- sentinel_frame->prev_p = 1;;
- this_frame->prev_arch.p = 1;
- this_frame->prev_arch.arch = get_regcache_arch (regcache);
- this_frame->next = sentinel_frame;
-
- return this_frame;
-}
-#endif
-
/* Create an arbitrary (i.e. address specified by user) or innermost frame.
Always returns a non-NULL value. */
diff --git a/gdb/frame.h b/gdb/frame.h
index 0249857..1b72610 100644
--- a/gdb/frame.h
+++ b/gdb/frame.h
@@ -833,14 +833,6 @@ extern struct frame_info *deprecated_safe_get_selected_frame (void);
extern struct frame_info *create_new_frame (CORE_ADDR base, CORE_ADDR pc);
-#if GDB_SELF_TEST
-
-/* Create a frame for unit test. Its next frame is sentinel frame,
- created from REGCACHE. */
-
-extern struct frame_info *create_test_frame (struct regcache *regcache);
-#endif
-
/* Return true if the frame unwinder for frame FI is UNWINDER; false
otherwise. */
diff --git a/gdb/gdbarch-selftests.c b/gdb/gdbarch-selftests.c
index f0b8d5d..58ed112 100644
--- a/gdb/gdbarch-selftests.c
+++ b/gdb/gdbarch-selftests.c
@@ -22,25 +22,57 @@
#include "selftest.h"
#include "selftest-arch.h"
#include "inferior.h"
+#include "gdbthread.h"
+#include "target.h"
namespace selftests {
-/* A read-write regcache which doesn't write the target. */
+/* A mock process_stratum target_ops that doesn't read/write registers
+ anywhere. */
-class regcache_test : public regcache
+static int
+test_target_has_registers (target_ops *self)
{
-public:
- explicit regcache_test (struct gdbarch *gdbarch)
- : regcache (gdbarch, NULL, false)
- {
- set_ptid (inferior_ptid);
+ return 1;
+}
- current_regcache.push_front (this);
- }
+static int
+test_target_has_stack (target_ops *self)
+{
+ return 1;
+}
+
+static int
+test_target_has_memory (target_ops *self)
+{
+ return 1;
+}
+
+static void
+test_target_prepare_to_store (target_ops *self, regcache *regs)
+{
+}
+
+static void
+test_target_store_registers (target_ops *self, regcache *regs, int regno)
+{
+}
- void raw_write (int regnum, const gdb_byte *buf) override
+class test_target_ops : public target_ops
+{
+public:
+ test_target_ops ()
+ : target_ops {}
{
- raw_set_cached_value (regnum, buf);
+ to_magic = OPS_MAGIC;
+ to_stratum = process_stratum;
+ to_has_memory = test_target_has_memory;
+ to_has_stack = test_target_has_stack;
+ to_has_registers = test_target_has_registers;
+ to_prepare_to_store = test_target_prepare_to_store;
+ to_store_registers = test_target_store_registers;
+
+ complete_target_initialization (this);
}
};
@@ -84,15 +116,56 @@ register_to_value_test (struct gdbarch *gdbarch)
builtin->builtin_char32,
};
- current_inferior()->gdbarch = gdbarch;
+ /* Error out if debugging something, because we're going to push the
+ test target, which would pop any existing target. */
+ if (current_target.to_stratum >= process_stratum)
+ error (_("target already pushed"));
+
+ /* Create a mock environment. An inferior with a thread, with a
+ process_stratum target pushed. */
+
+ test_target_ops mock_target;
+ ptid_t mock_ptid (1, 1);
+ inferior mock_inferior (mock_ptid.pid ());
+ address_space mock_aspace {};
+ mock_inferior.gdbarch = gdbarch;
+ mock_inferior.aspace = &mock_aspace;
+ thread_info mock_thread (&mock_inferior, mock_ptid);
+
+ scoped_restore restore_thread_list
+ = make_scoped_restore (&thread_list, &mock_thread);
+
+ /* Add the mock inferior to the inferior list so that look ups by
+ target+ptid can find it. */
+ scoped_restore restore_inferior_list
+ = make_scoped_restore (&inferior_list);
+ inferior_list = &mock_inferior;
+
+ /* Switch to the mock inferior. */
+ scoped_restore_current_inferior restore_current_inferior;
+ set_current_inferior (&mock_inferior);
+
+ /* Push the process_stratum target so we can mock accessing
+ registers. */
+ push_target (&mock_target);
+
+ /* Pop it again on exit (return/exception). */
+ struct on_exit
+ {
+ ~on_exit ()
+ {
+ pop_all_targets_at_and_above (process_stratum);
+ }
+ } pop_targets;
+
+ /* Switch to the mock thread. */
+ scoped_restore restore_inferior_ptid
+ = make_scoped_restore (&inferior_ptid, mock_ptid);
- struct regcache *regcache = new regcache_test (gdbarch);
- struct frame_info *frame = create_test_frame (regcache);
+ struct frame_info *frame = get_current_frame ();
const int num_regs = (gdbarch_num_regs (gdbarch)
+ gdbarch_num_pseudo_regs (gdbarch));
- SELF_CHECK (regcache == get_current_regcache ());
-
/* Test gdbarch methods register_to_value and value_to_register with
different combinations of register numbers and types. */
for (const auto &type : types)
diff --git a/gdb/progspace.c b/gdb/progspace.c
index 41e8cd0..ea328c8 100644
--- a/gdb/progspace.c
+++ b/gdb/progspace.c
@@ -44,18 +44,6 @@ static int highest_address_space_num;
DEFINE_REGISTRY (program_space, REGISTRY_ACCESS_FIELD)
-/* An address space. It is used for comparing if pspaces/inferior/threads
- see the same address space and for associating caches to each address
- space. */
-
-struct address_space
-{
- int num;
-
- /* Per aspace data-pointers required by other GDB modules. */
- REGISTRY_FIELDS;
-};
-
/* Keep a registry of per-address_space data-pointers required by other GDB
modules. */
diff --git a/gdb/progspace.h b/gdb/progspace.h
index f679fe3..85c99a62 100644
--- a/gdb/progspace.h
+++ b/gdb/progspace.h
@@ -210,6 +210,17 @@ struct program_space
REGISTRY_FIELDS;
};
+/* An address space. It is used for comparing if
+ pspaces/inferior/threads see the same address space and for
+ associating caches to each address space. */
+struct address_space
+{
+ int num;
+
+ /* Per aspace data-pointers required by other GDB modules. */
+ REGISTRY_FIELDS;
+};
+
/* The object file that the main symbol table was loaded from (e.g. the
argument to the "symbol-file" or "file" command). */
diff --git a/gdb/regcache.h b/gdb/regcache.h
index 3ecdb3b..6f42fb9 100644
--- a/gdb/regcache.h
+++ b/gdb/regcache.h
@@ -252,11 +252,6 @@ public:
DISABLE_COPY_AND_ASSIGN (regcache);
- /* class regcache is only extended in unit test, so only mark it
- virtual when selftest is enabled. */
-#if GDB_SELF_TEST
- virtual
-#endif
~regcache ()
{
xfree (m_registers);
@@ -277,11 +272,6 @@ public:
enum register_status raw_read (int regnum, gdb_byte *buf);
- /* class regcache is only extended in unit test, so only mark it
- virtual when selftest is enabled. */
-#if GDB_SELF_TEST
- virtual
-#endif
void raw_write (int regnum, const gdb_byte *buf);
template<typename T, typename = RequireLongest<T>>