1import gdbremote_testcase
2from lldbsuite.test.decorators import *
3from lldbsuite.test.lldbtest import *
4from lldbsuite.test import lldbutil
5
6
7class TestGdbRemoteExpeditedRegisters(
8        gdbremote_testcase.GdbRemoteTestCaseBase):
9
10    mydir = TestBase.compute_mydir(__file__)
11    @skipIfDarwinEmbedded # <rdar://problem/34539270> lldb-server tests not updated to work on ios etc yet
12
13    def gather_expedited_registers(self):
14        # Setup the stub and set the gdb remote command stream.
15        procs = self.prep_debug_monitor_and_inferior(inferior_args=["sleep:2"])
16        self.test_sequence.add_log_lines([
17            # Start up the inferior.
18            "read packet: $c#63",
19            # Immediately tell it to stop.  We want to see what it reports.
20            "read packet: {}".format(chr(3)),
21            {"direction": "send",
22             "regex": r"^\$T([0-9a-fA-F]+)([^#]+)#[0-9a-fA-F]{2}$",
23             "capture": {1: "stop_result",
24                         2: "key_vals_text"}},
25        ], True)
26
27        # Run the gdb remote command stream.
28        context = self.expect_gdbremote_sequence()
29        self.assertIsNotNone(context)
30
31        # Pull out expedited registers.
32        key_vals_text = context.get("key_vals_text")
33        self.assertIsNotNone(key_vals_text)
34
35        expedited_registers = self.extract_registers_from_stop_notification(
36            key_vals_text)
37        self.assertIsNotNone(expedited_registers)
38
39        return expedited_registers
40
41    def stop_notification_contains_generic_register(
42            self, generic_register_name):
43        # Generate a stop reply, parse out expedited registers from stop
44        # notification.
45        expedited_registers = self.gather_expedited_registers()
46        self.assertIsNotNone(expedited_registers)
47        self.assertTrue(len(expedited_registers) > 0)
48
49        # Gather target register infos.
50        reg_infos = self.gather_register_infos()
51
52        # Find the generic register.
53        reg_info = self.find_generic_register_with_name(
54            reg_infos, generic_register_name)
55        self.assertIsNotNone(reg_info)
56
57        # Ensure the expedited registers contained it.
58        self.assertTrue(reg_info["lldb_register_index"] in expedited_registers)
59        self.trace("{} reg_info:{}".format(generic_register_name, reg_info))
60
61    def stop_notification_contains_any_registers(self):
62        # Generate a stop reply, parse out expedited registers from stop
63        # notification.
64        expedited_registers = self.gather_expedited_registers()
65        # Verify we have at least one expedited register.
66        self.assertTrue(len(expedited_registers) > 0)
67
68    @debugserver_test
69    def test_stop_notification_contains_any_registers_debugserver(self):
70        self.init_debugserver_test()
71        self.build()
72        self.set_inferior_startup_launch()
73        self.stop_notification_contains_any_registers()
74
75    @llgs_test
76    def test_stop_notification_contains_any_registers_llgs(self):
77        self.init_llgs_test()
78        self.build()
79        self.set_inferior_startup_launch()
80        self.stop_notification_contains_any_registers()
81
82    def stop_notification_contains_no_duplicate_registers(self):
83        # Generate a stop reply, parse out expedited registers from stop
84        # notification.
85        expedited_registers = self.gather_expedited_registers()
86        # Verify no expedited register was specified multiple times.
87        for (reg_num, value) in list(expedited_registers.items()):
88            if (isinstance(value, list)) and (len(value) > 0):
89                self.fail(
90                    "expedited register number {} specified more than once ({} times)".format(
91                        reg_num, len(value)))
92
93    @debugserver_test
94    def test_stop_notification_contains_no_duplicate_registers_debugserver(
95            self):
96        self.init_debugserver_test()
97        self.build()
98        self.set_inferior_startup_launch()
99        self.stop_notification_contains_no_duplicate_registers()
100
101    @llgs_test
102    def test_stop_notification_contains_no_duplicate_registers_llgs(self):
103        self.init_llgs_test()
104        self.build()
105        self.set_inferior_startup_launch()
106        self.stop_notification_contains_no_duplicate_registers()
107
108    def stop_notification_contains_pc_register(self):
109        self.stop_notification_contains_generic_register("pc")
110
111    @debugserver_test
112    def test_stop_notification_contains_pc_register_debugserver(self):
113        self.init_debugserver_test()
114        self.build()
115        self.set_inferior_startup_launch()
116        self.stop_notification_contains_pc_register()
117
118    @llgs_test
119    def test_stop_notification_contains_pc_register_llgs(self):
120        self.init_llgs_test()
121        self.build()
122        self.set_inferior_startup_launch()
123        self.stop_notification_contains_pc_register()
124
125    # powerpc64 has no FP register
126    @skipIf(triple='^powerpc64')
127    def stop_notification_contains_fp_register(self):
128        self.stop_notification_contains_generic_register("fp")
129
130    @debugserver_test
131    def test_stop_notification_contains_fp_register_debugserver(self):
132        self.init_debugserver_test()
133        self.build()
134        self.set_inferior_startup_launch()
135        self.stop_notification_contains_fp_register()
136
137    @llgs_test
138    def test_stop_notification_contains_fp_register_llgs(self):
139        self.init_llgs_test()
140        self.build()
141        self.set_inferior_startup_launch()
142        self.stop_notification_contains_fp_register()
143
144    def stop_notification_contains_sp_register(self):
145        self.stop_notification_contains_generic_register("sp")
146
147    @debugserver_test
148    def test_stop_notification_contains_sp_register_debugserver(self):
149        self.init_debugserver_test()
150        self.build()
151        self.set_inferior_startup_launch()
152        self.stop_notification_contains_sp_register()
153
154    @llgs_test
155    def test_stop_notification_contains_sp_register_llgs(self):
156        self.init_llgs_test()
157        self.build()
158        self.set_inferior_startup_launch()
159        self.stop_notification_contains_sp_register()
160