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