/* Self tests for gdbarch for GDB, the GNU debugger.
- Copyright (C) 2017 Free Software Foundation, Inc.
+ Copyright (C) 2017-2020 Free Software Foundation, Inc.
This file is part of GDB.
#include "defs.h"
#if GDB_SELF_TEST
-#include "selftest.h"
+#include "gdbsupport/selftest.h"
#include "selftest-arch.h"
#include "inferior.h"
+#include "gdbthread.h"
+#include "target.h"
+#include "test-target.h"
+#include "target-float.h"
+#include "gdbsupport/def-vector.h"
+#include "gdbarch.h"
namespace selftests {
-/* A read-write regcache which doesn't write the target. */
-
-class regcache_test : public regcache
-{
-public:
- explicit regcache_test (struct gdbarch *gdbarch)
- : regcache (gdbarch, NULL, false)
- {
- set_ptid (inferior_ptid);
-
- current_regcache.push_front (this);
- }
-
- void raw_write (int regnum, const gdb_byte *buf) override
- {
- raw_set_cached_value (regnum, buf);
- }
-};
-
/* Test gdbarch methods register_to_value and value_to_register. */
static void
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_top_target ()->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);
- struct regcache *regcache = new regcache_test (gdbarch);
- struct frame_info *frame = create_test_frame (regcache);
- const int num_regs = (gdbarch_num_regs (gdbarch)
- + gdbarch_num_pseudo_regs (gdbarch));
+ scoped_restore restore_thread_list
+ = make_scoped_restore (&mock_inferior.thread_list, &mock_thread);
- SELF_CHECK (regcache == get_current_regcache ());
+ /* 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). */
+ SCOPE_EXIT { pop_all_targets_at_and_above (process_stratum); };
+
+ /* Switch to the mock thread. */
+ scoped_restore restore_inferior_ptid
+ = make_scoped_restore (&inferior_ptid, mock_ptid);
+
+ struct frame_info *frame = get_current_frame ();
+ const int num_regs = gdbarch_num_cooked_regs (gdbarch);
/* Test gdbarch methods register_to_value and value_to_register with
different combinations of register numbers and types. */
if (TYPE_CODE (type) == TYPE_CODE_FLT)
{
- DOUBLEST d = 1.25;
-
/* Generate valid float format. */
- floatformat_from_doublest (floatformat_from_type (type),
- &d, expected.data ());
+ target_float_from_string (expected.data (), type, "1.25");
}
else
{
_initialize_gdbarch_selftests (void)
{
#if GDB_SELF_TEST
- selftests::register_test_foreach_arch (selftests::register_to_value_test);
+ selftests::register_test_foreach_arch ("register_to_value",
+ selftests::register_to_value_test);
#endif
}