diff options
-rw-r--r-- | gdb/ChangeLog | 19 | ||||
-rw-r--r-- | gdb/frame.c | 17 | ||||
-rw-r--r-- | gdb/frame.h | 8 | ||||
-rw-r--r-- | gdb/gdbarch-selftests.c | 105 | ||||
-rw-r--r-- | gdb/progspace.c | 12 | ||||
-rw-r--r-- | gdb/progspace.h | 11 | ||||
-rw-r--r-- | gdb/regcache.h | 10 |
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>> |