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