1
2
3import gdbremote_testcase
4import textwrap
5from lldbsuite.test.decorators import *
6from lldbsuite.test.lldbtest import *
7from lldbsuite.test import lldbutil
8
9
10def _extract_register_value(reg_info, reg_bank, byte_order, bytes_per_entry=8):
11    reg_offset = int(reg_info["offset"])*2
12    reg_byte_size = int(2 * int(reg_info["bitsize"]) / 8)
13    # Create slice with the contents of the register.
14    reg_slice = reg_bank[reg_offset:reg_offset+reg_byte_size]
15
16    reg_value = []
17    # Wrap slice according to bytes_per_entry.
18    for entry in textwrap.wrap(reg_slice, 2 * bytes_per_entry):
19        # Invert the bytes order if target uses little-endian.
20        if byte_order == lldb.eByteOrderLittle:
21            entry = "".join(reversed([entry[i:i+2] for i in range(0,
22                                          len(entry),2)]))
23        reg_value.append("0x" + entry)
24
25    return reg_value
26
27
28class TestGdbRemoteGPacket(gdbremote_testcase.GdbRemoteTestCaseBase):
29
30    mydir = TestBase.compute_mydir(__file__)
31
32    def run_test_g_packet(self):
33        self.build()
34        self.prep_debug_monitor_and_inferior()
35        self.test_sequence.add_log_lines(
36            ["read packet: $g#67",
37             {"direction": "send", "regex": r"^\$(.+)#[0-9a-fA-F]{2}$",
38              "capture": {1: "register_bank"}}],
39            True)
40        context = self.expect_gdbremote_sequence()
41        register_bank = context.get("register_bank")
42        self.assertNotEqual(register_bank[0], 'E')
43
44        self.test_sequence.add_log_lines(
45            ["read packet: $G" + register_bank + "#00",
46             {"direction": "send", "regex": r"^\$(.+)#[0-9a-fA-F]{2}$",
47              "capture": {1: "G_reply"}}],
48            True)
49        context = self.expect_gdbremote_sequence()
50        self.assertNotEqual(context.get("G_reply")[0], 'E')
51
52    @skipIfOutOfTreeDebugserver
53    @debugserver_test
54    @skipIfDarwinEmbedded
55    def test_g_packet_debugserver(self):
56        self.init_debugserver_test()
57        self.run_test_g_packet()
58
59    @skipIf(archs=no_match(["x86_64"]))
60    def g_returns_correct_data(self, with_suffix):
61        procs = self.prep_debug_monitor_and_inferior()
62
63        self.add_register_info_collection_packets()
64        if with_suffix:
65            self.add_thread_suffix_request_packets()
66        self.add_threadinfo_collection_packets()
67        context = self.expect_gdbremote_sequence()
68        self.assertIsNotNone(context)
69
70        # Gather register info.
71        reg_infos = self.parse_register_info_packets(context)
72        self.assertIsNotNone(reg_infos)
73        self.add_lldb_register_index(reg_infos)
74        # Index register info entries by name.
75        reg_infos = {info['name']: info for info in reg_infos}
76
77        # Gather thread info.
78        if with_suffix:
79            threads = self.parse_threadinfo_packets(context)
80            self.assertIsNotNone(threads)
81            thread_id = threads[0]
82            self.assertIsNotNone(thread_id)
83        else:
84            thread_id = None
85
86        # Send vCont packet to resume the inferior.
87        self.test_sequence.add_log_lines(["read packet: $vCont;c#a8",
88                                          {"direction": "send",
89                                           "regex": r"^\$T([0-9a-fA-F]{2}).*#[0-9a-fA-F]{2}$",
90                                           "capture": {1: "hex_exit_code"}},
91                                          ],
92                                         True)
93
94        # Send g packet to retrieve the register bank
95        if thread_id:
96            g_request = "read packet: $g;thread:{:x}#00".format(thread_id)
97        else:
98            g_request = "read packet: $g#00"
99        self.test_sequence.add_log_lines(
100            [g_request,
101             {"direction": "send", "regex": r"^\$(.+)#[0-9a-fA-F]{2}$",
102              "capture": {1: "register_bank"}}],
103            True)
104        context = self.expect_gdbremote_sequence()
105        self.assertIsNotNone(context)
106        reg_bank = context.get("register_bank")
107        self.assertNotEqual(reg_bank[0], 'E')
108
109        byte_order = self.get_target_byte_order()
110        get_reg_value = lambda reg_name : _extract_register_value(
111            reg_infos[reg_name], reg_bank, byte_order)
112
113        self.assertEqual(['0x0102030405060708'], get_reg_value('r8'))
114        self.assertEqual(['0x1112131415161718'], get_reg_value('r9'))
115        self.assertEqual(['0x2122232425262728'], get_reg_value('r10'))
116        self.assertEqual(['0x3132333435363738'], get_reg_value('r11'))
117        self.assertEqual(['0x4142434445464748'], get_reg_value('r12'))
118        self.assertEqual(['0x5152535455565758'], get_reg_value('r13'))
119        self.assertEqual(['0x6162636465666768'], get_reg_value('r14'))
120        self.assertEqual(['0x7172737475767778'], get_reg_value('r15'))
121
122        self.assertEqual(
123            ['0x020406080a0c0e01', '0x030507090b0d0f00'], get_reg_value('xmm8'))
124        self.assertEqual(
125            ['0x121416181a1c1e11', '0x131517191b1d1f10'], get_reg_value('xmm9'))
126        self.assertEqual(
127            ['0x222426282a2c2e21', '0x232527292b2d2f20'], get_reg_value('xmm10'))
128        self.assertEqual(
129            ['0x323436383a3c3e31', '0x333537393b3d3f30'], get_reg_value('xmm11'))
130        self.assertEqual(
131            ['0x424446484a4c4e41', '0x434547494b4d4f40'], get_reg_value('xmm12'))
132        self.assertEqual(
133            ['0x525456585a5c5e51', '0x535557595b5d5f50'], get_reg_value('xmm13'))
134        self.assertEqual(
135            ['0x626466686a6c6e61', '0x636567696b6d6f60'], get_reg_value('xmm14'))
136        self.assertEqual(
137            ['0x727476787a7c7e71', '0x737577797b7d7f70'], get_reg_value('xmm15'))
138
139    @expectedFailureAll(oslist=["freebsd", "netbsd"])
140    @llgs_test
141    def test_g_returns_correct_data_with_suffix_llgs(self):
142        self.init_llgs_test()
143        self.build()
144        self.set_inferior_startup_launch()
145        self.g_returns_correct_data(True)
146
147    @expectedFailureAll(oslist=["freebsd", "netbsd"])
148    @llgs_test
149    def test_g_returns_correct_data_no_suffix_llgs(self):
150        self.init_llgs_test()
151        self.build()
152        self.set_inferior_startup_launch()
153        self.g_returns_correct_data(False)
154