xref: /llvm-project/lldb/test/API/tools/lldb-server/TestGdbRemoteRegisterState.py (revision 9c2468821ec51defd09c246fea4a47886fff8c01)
199451b44SJordan Rupprechtimport gdbremote_testcase
299451b44SJordan Rupprechtfrom lldbsuite.test.decorators import *
399451b44SJordan Rupprechtfrom lldbsuite.test.lldbtest import *
499451b44SJordan Rupprechtfrom lldbsuite.test import lldbutil
599451b44SJordan Rupprecht
699451b44SJordan Rupprecht
799451b44SJordan Rupprechtclass TestGdbRemoteRegisterState(gdbremote_testcase.GdbRemoteTestCaseBase):
899451b44SJordan Rupprecht    """Test QSaveRegisterState/QRestoreRegisterState support."""
999451b44SJordan Rupprecht
1099451b44SJordan Rupprecht    def grp_register_save_restore_works(self, with_suffix):
1199451b44SJordan Rupprecht        # Start up the process, use thread suffix, grab main thread id.
1299451b44SJordan Rupprecht        inferior_args = ["message:main entered", "sleep:5"]
132238dcc3SJonas Devlieghere        procs = self.prep_debug_monitor_and_inferior(inferior_args=inferior_args)
1499451b44SJordan Rupprecht
1599451b44SJordan Rupprecht        self.add_process_info_collection_packets()
1699451b44SJordan Rupprecht        self.add_register_info_collection_packets()
1799451b44SJordan Rupprecht        if with_suffix:
1899451b44SJordan Rupprecht            self.add_thread_suffix_request_packets()
1999451b44SJordan Rupprecht        self.add_threadinfo_collection_packets()
2099451b44SJordan Rupprecht
2199451b44SJordan Rupprecht        context = self.expect_gdbremote_sequence()
2299451b44SJordan Rupprecht        self.assertIsNotNone(context)
2399451b44SJordan Rupprecht
2499451b44SJordan Rupprecht        # Gather process info.
2599451b44SJordan Rupprecht        process_info = self.parse_process_info_response(context)
2699451b44SJordan Rupprecht        endian = process_info.get("endian")
2799451b44SJordan Rupprecht        self.assertIsNotNone(endian)
2899451b44SJordan Rupprecht
2999451b44SJordan Rupprecht        # Gather register info.
3099451b44SJordan Rupprecht        reg_infos = self.parse_register_info_packets(context)
3199451b44SJordan Rupprecht        self.assertIsNotNone(reg_infos)
3299451b44SJordan Rupprecht        self.add_lldb_register_index(reg_infos)
3399451b44SJordan Rupprecht
3499451b44SJordan Rupprecht        # Pull out the register infos that we think we can bit flip
3599451b44SJordan Rupprecht        # successfully.
3699451b44SJordan Rupprecht        gpr_reg_infos = [
372238dcc3SJonas Devlieghere            reg_info
382238dcc3SJonas Devlieghere            for reg_info in reg_infos
392238dcc3SJonas Devlieghere            if self.is_bit_flippable_register(reg_info)
402238dcc3SJonas Devlieghere        ]
41*9c246882SJordan Rupprecht        self.assertGreater(len(gpr_reg_infos), 0)
4299451b44SJordan Rupprecht
4399451b44SJordan Rupprecht        # Gather thread info.
4499451b44SJordan Rupprecht        if with_suffix:
4599451b44SJordan Rupprecht            threads = self.parse_threadinfo_packets(context)
4699451b44SJordan Rupprecht            self.assertIsNotNone(threads)
4799451b44SJordan Rupprecht            thread_id = threads[0]
4899451b44SJordan Rupprecht            self.assertIsNotNone(thread_id)
49b321b429SJonas Devlieghere            self.trace("Running on thread: 0x{:x}".format(thread_id))
5099451b44SJordan Rupprecht        else:
5199451b44SJordan Rupprecht            thread_id = None
5299451b44SJordan Rupprecht
5399451b44SJordan Rupprecht        # Save register state.
5499451b44SJordan Rupprecht        self.reset_test_sequence()
5599451b44SJordan Rupprecht        self.add_QSaveRegisterState_packets(thread_id)
5699451b44SJordan Rupprecht
5799451b44SJordan Rupprecht        context = self.expect_gdbremote_sequence()
5899451b44SJordan Rupprecht        self.assertIsNotNone(context)
5999451b44SJordan Rupprecht
6099451b44SJordan Rupprecht        (success, state_id) = self.parse_QSaveRegisterState_response(context)
6199451b44SJordan Rupprecht        self.assertTrue(success)
6299451b44SJordan Rupprecht        self.assertIsNotNone(state_id)
63b321b429SJonas Devlieghere        self.trace("saved register state id: {}".format(state_id))
6499451b44SJordan Rupprecht
6599451b44SJordan Rupprecht        # Remember initial register values.
6699451b44SJordan Rupprecht        initial_reg_values = self.read_register_values(
672238dcc3SJonas Devlieghere            gpr_reg_infos, endian, thread_id=thread_id
682238dcc3SJonas Devlieghere        )
69b321b429SJonas Devlieghere        self.trace("initial_reg_values: {}".format(initial_reg_values))
7099451b44SJordan Rupprecht
7199451b44SJordan Rupprecht        # Flip gpr register values.
7299451b44SJordan Rupprecht        (successful_writes, failed_writes) = self.flip_all_bits_in_each_register_value(
732238dcc3SJonas Devlieghere            gpr_reg_infos, endian, thread_id=thread_id
742238dcc3SJonas Devlieghere        )
752238dcc3SJonas Devlieghere        self.trace(
762238dcc3SJonas Devlieghere            "successful writes: {}, failed writes: {}".format(
772238dcc3SJonas Devlieghere                successful_writes, failed_writes
782238dcc3SJonas Devlieghere            )
792238dcc3SJonas Devlieghere        )
80*9c246882SJordan Rupprecht        self.assertGreater(successful_writes, 0)
8199451b44SJordan Rupprecht
8299451b44SJordan Rupprecht        flipped_reg_values = self.read_register_values(
832238dcc3SJonas Devlieghere            gpr_reg_infos, endian, thread_id=thread_id
842238dcc3SJonas Devlieghere        )
85b321b429SJonas Devlieghere        self.trace("flipped_reg_values: {}".format(flipped_reg_values))
8699451b44SJordan Rupprecht
8799451b44SJordan Rupprecht        # Restore register values.
8899451b44SJordan Rupprecht        self.reset_test_sequence()
8999451b44SJordan Rupprecht        self.add_QRestoreRegisterState_packets(state_id, thread_id)
9099451b44SJordan Rupprecht
9199451b44SJordan Rupprecht        context = self.expect_gdbremote_sequence()
9299451b44SJordan Rupprecht        self.assertIsNotNone(context)
9399451b44SJordan Rupprecht
9499451b44SJordan Rupprecht        # Verify registers match initial register values.
9599451b44SJordan Rupprecht        final_reg_values = self.read_register_values(
962238dcc3SJonas Devlieghere            gpr_reg_infos, endian, thread_id=thread_id
972238dcc3SJonas Devlieghere        )
98b321b429SJonas Devlieghere        self.trace("final_reg_values: {}".format(final_reg_values))
9999451b44SJordan Rupprecht        self.assertIsNotNone(final_reg_values)
10099451b44SJordan Rupprecht        self.assertEqual(final_reg_values, initial_reg_values)
10199451b44SJordan Rupprecht
1020a8a2453SPavel Labath    def test_grp_register_save_restore_works_with_suffix(self):
10399451b44SJordan Rupprecht        USE_THREAD_SUFFIX = True
10499451b44SJordan Rupprecht        self.build()
10599451b44SJordan Rupprecht        self.set_inferior_startup_launch()
10699451b44SJordan Rupprecht        self.grp_register_save_restore_works(USE_THREAD_SUFFIX)
10799451b44SJordan Rupprecht
1080a8a2453SPavel Labath    def test_grp_register_save_restore_works_no_suffix(self):
10999451b44SJordan Rupprecht        USE_THREAD_SUFFIX = False
11099451b44SJordan Rupprecht        self.build()
11199451b44SJordan Rupprecht        self.set_inferior_startup_launch()
11299451b44SJordan Rupprecht        self.grp_register_save_restore_works(USE_THREAD_SUFFIX)
113