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"] 1399451b44SJordan Rupprecht procs = self.prep_debug_monitor_and_inferior( 1499451b44SJordan Rupprecht inferior_args=inferior_args) 1599451b44SJordan Rupprecht 1699451b44SJordan Rupprecht self.add_process_info_collection_packets() 1799451b44SJordan Rupprecht self.add_register_info_collection_packets() 1899451b44SJordan Rupprecht if with_suffix: 1999451b44SJordan Rupprecht self.add_thread_suffix_request_packets() 2099451b44SJordan Rupprecht self.add_threadinfo_collection_packets() 2199451b44SJordan Rupprecht 2299451b44SJordan Rupprecht context = self.expect_gdbremote_sequence() 2399451b44SJordan Rupprecht self.assertIsNotNone(context) 2499451b44SJordan Rupprecht 2599451b44SJordan Rupprecht # Gather process info. 2699451b44SJordan Rupprecht process_info = self.parse_process_info_response(context) 2799451b44SJordan Rupprecht endian = process_info.get("endian") 2899451b44SJordan Rupprecht self.assertIsNotNone(endian) 2999451b44SJordan Rupprecht 3099451b44SJordan Rupprecht # Gather register info. 3199451b44SJordan Rupprecht reg_infos = self.parse_register_info_packets(context) 3299451b44SJordan Rupprecht self.assertIsNotNone(reg_infos) 3399451b44SJordan Rupprecht self.add_lldb_register_index(reg_infos) 3499451b44SJordan Rupprecht 3599451b44SJordan Rupprecht # Pull out the register infos that we think we can bit flip 3699451b44SJordan Rupprecht # successfully. 3799451b44SJordan Rupprecht gpr_reg_infos = [ 3899451b44SJordan Rupprecht reg_info for reg_info in reg_infos if self.is_bit_flippable_register(reg_info)] 3999451b44SJordan Rupprecht self.assertTrue(len(gpr_reg_infos) > 0) 4099451b44SJordan Rupprecht 4199451b44SJordan Rupprecht # Gather thread info. 4299451b44SJordan Rupprecht if with_suffix: 4399451b44SJordan Rupprecht threads = self.parse_threadinfo_packets(context) 4499451b44SJordan Rupprecht self.assertIsNotNone(threads) 4599451b44SJordan Rupprecht thread_id = threads[0] 4699451b44SJordan Rupprecht self.assertIsNotNone(thread_id) 47b321b429SJonas Devlieghere self.trace("Running on thread: 0x{:x}".format(thread_id)) 4899451b44SJordan Rupprecht else: 4999451b44SJordan Rupprecht thread_id = None 5099451b44SJordan Rupprecht 5199451b44SJordan Rupprecht # Save register state. 5299451b44SJordan Rupprecht self.reset_test_sequence() 5399451b44SJordan Rupprecht self.add_QSaveRegisterState_packets(thread_id) 5499451b44SJordan Rupprecht 5599451b44SJordan Rupprecht context = self.expect_gdbremote_sequence() 5699451b44SJordan Rupprecht self.assertIsNotNone(context) 5799451b44SJordan Rupprecht 5899451b44SJordan Rupprecht (success, state_id) = self.parse_QSaveRegisterState_response(context) 5999451b44SJordan Rupprecht self.assertTrue(success) 6099451b44SJordan Rupprecht self.assertIsNotNone(state_id) 61b321b429SJonas Devlieghere self.trace("saved register state id: {}".format(state_id)) 6299451b44SJordan Rupprecht 6399451b44SJordan Rupprecht # Remember initial register values. 6499451b44SJordan Rupprecht initial_reg_values = self.read_register_values( 6599451b44SJordan Rupprecht gpr_reg_infos, endian, thread_id=thread_id) 66b321b429SJonas Devlieghere self.trace("initial_reg_values: {}".format(initial_reg_values)) 6799451b44SJordan Rupprecht 6899451b44SJordan Rupprecht # Flip gpr register values. 6999451b44SJordan Rupprecht (successful_writes, failed_writes) = self.flip_all_bits_in_each_register_value( 7099451b44SJordan Rupprecht gpr_reg_infos, endian, thread_id=thread_id) 71b321b429SJonas Devlieghere self.trace("successful writes: {}, failed writes: {}".format(successful_writes, failed_writes)) 7299451b44SJordan Rupprecht self.assertTrue(successful_writes > 0) 7399451b44SJordan Rupprecht 7499451b44SJordan Rupprecht flipped_reg_values = self.read_register_values( 7599451b44SJordan Rupprecht gpr_reg_infos, endian, thread_id=thread_id) 76b321b429SJonas Devlieghere self.trace("flipped_reg_values: {}".format(flipped_reg_values)) 7799451b44SJordan Rupprecht 7899451b44SJordan Rupprecht # Restore register values. 7999451b44SJordan Rupprecht self.reset_test_sequence() 8099451b44SJordan Rupprecht self.add_QRestoreRegisterState_packets(state_id, thread_id) 8199451b44SJordan Rupprecht 8299451b44SJordan Rupprecht context = self.expect_gdbremote_sequence() 8399451b44SJordan Rupprecht self.assertIsNotNone(context) 8499451b44SJordan Rupprecht 8599451b44SJordan Rupprecht # Verify registers match initial register values. 8699451b44SJordan Rupprecht final_reg_values = self.read_register_values( 8799451b44SJordan Rupprecht gpr_reg_infos, endian, thread_id=thread_id) 88b321b429SJonas Devlieghere self.trace("final_reg_values: {}".format(final_reg_values)) 8999451b44SJordan Rupprecht self.assertIsNotNone(final_reg_values) 9099451b44SJordan Rupprecht self.assertEqual(final_reg_values, initial_reg_values) 9199451b44SJordan Rupprecht 92*0a8a2453SPavel Labath def test_grp_register_save_restore_works_with_suffix(self): 9399451b44SJordan Rupprecht USE_THREAD_SUFFIX = True 9499451b44SJordan Rupprecht self.build() 9599451b44SJordan Rupprecht self.set_inferior_startup_launch() 9699451b44SJordan Rupprecht self.grp_register_save_restore_works(USE_THREAD_SUFFIX) 9799451b44SJordan Rupprecht 98*0a8a2453SPavel Labath def test_grp_register_save_restore_works_no_suffix(self): 9999451b44SJordan Rupprecht USE_THREAD_SUFFIX = False 10099451b44SJordan Rupprecht self.build() 10199451b44SJordan Rupprecht self.set_inferior_startup_launch() 10299451b44SJordan Rupprecht self.grp_register_save_restore_works(USE_THREAD_SUFFIX) 103