1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
|
import unittest2
import gdbremote_testcase
from lldbtest import *
class TestGdbRemoteRegisterState(gdbremote_testcase.GdbRemoteTestCaseBase):
"""Test QSaveRegisterState/QRestoreRegisterState support."""
def grp_register_save_restore_works(self, with_suffix):
# Start up the process, use thread suffix, grab main thread id.
inferior_args = ["message:main entered", "sleep:5"]
procs = self.prep_debug_monitor_and_inferior(inferior_args=inferior_args)
self.add_process_info_collection_packets()
self.add_register_info_collection_packets()
if with_suffix:
self.add_thread_suffix_request_packets()
self.add_threadinfo_collection_packets()
self.test_sequence.add_log_lines([
# Start the inferior...
"read packet: $c#63",
# ... match output....
{ "type":"output_match", "regex":r"^message:main entered\r\n$" },
], True)
# ... then interrupt.
self.add_interrupt_packets()
context = self.expect_gdbremote_sequence()
self.assertIsNotNone(context)
# Gather process info.
process_info = self.parse_process_info_response(context)
endian = process_info.get("endian")
self.assertIsNotNone(endian)
# Gather register info.
reg_infos = self.parse_register_info_packets(context)
self.assertIsNotNone(reg_infos)
self.add_lldb_register_index(reg_infos)
# Pull out the register infos that we think we can bit flip successfully.
gpr_reg_infos = [reg_info for reg_info in reg_infos if self.is_bit_flippable_register(reg_info)]
self.assertTrue(len(gpr_reg_infos) > 0)
# Gather thread info.
if with_suffix:
threads = self.parse_threadinfo_packets(context)
self.assertIsNotNone(threads)
thread_id = threads[0]
self.assertIsNotNone(thread_id)
# print "Running on thread: 0x{:x}".format(thread_id)
else:
thread_id = None
# Save register state.
self.reset_test_sequence()
self.add_QSaveRegisterState_packets(thread_id)
context = self.expect_gdbremote_sequence()
self.assertIsNotNone(context)
(success, state_id) = self.parse_QSaveRegisterState_response(context)
self.assertTrue(success)
self.assertIsNotNone(state_id)
# print "saved register state id: {}".format(state_id)
# Remember initial register values.
initial_reg_values = self.read_register_values(gpr_reg_infos, endian, thread_id=thread_id)
# print "initial_reg_values: {}".format(initial_reg_values)
# Flip gpr register values.
(successful_writes, failed_writes) = self.flip_all_bits_in_each_register_value(gpr_reg_infos, endian, thread_id=thread_id)
# print "successful writes: {}, failed writes: {}".format(successful_writes, failed_writes)
self.assertTrue(successful_writes > 0)
flipped_reg_values = self.read_register_values(gpr_reg_infos, endian, thread_id=thread_id)
# print "flipped_reg_values: {}".format(flipped_reg_values)
# Restore register values.
self.reset_test_sequence()
self.add_QRestoreRegisterState_packets(state_id, thread_id)
context = self.expect_gdbremote_sequence()
self.assertIsNotNone(context)
# Verify registers match initial register values.
final_reg_values = self.read_register_values(gpr_reg_infos, endian, thread_id=thread_id)
# print "final_reg_values: {}".format(final_reg_values)
self.assertIsNotNone(final_reg_values)
self.assertEquals(final_reg_values, initial_reg_values)
@debugserver_test
@dsym_test
def test_grp_register_save_restore_works_with_suffix_debugserver_dsym(self):
USE_THREAD_SUFFIX = True
self.init_debugserver_test()
self.buildDsym()
self.set_inferior_startup_launch()
self.grp_register_save_restore_works(USE_THREAD_SUFFIX)
@llgs_test
@dwarf_test
def test_grp_register_save_restore_works_with_suffix_llgs_dwarf(self):
USE_THREAD_SUFFIX = True
self.init_llgs_test()
self.buildDwarf()
self.set_inferior_startup_launch()
self.grp_register_save_restore_works(USE_THREAD_SUFFIX)
@debugserver_test
@dsym_test
def test_grp_register_save_restore_works_no_suffix_debugserver_dsym(self):
USE_THREAD_SUFFIX = False
self.init_debugserver_test()
self.buildDsym()
self.set_inferior_startup_launch()
self.grp_register_save_restore_works(USE_THREAD_SUFFIX)
@llgs_test
@dwarf_test
def test_grp_register_save_restore_works_no_suffix_llgs_dwarf(self):
USE_THREAD_SUFFIX = False
self.init_llgs_test()
self.buildDwarf()
self.set_inferior_startup_launch()
self.grp_register_save_restore_works(USE_THREAD_SUFFIX)
if __name__ == '__main__':
unittest2.main()
|