import gdbremote_testcase import lldbgdbserverutils from lldbsuite.test.decorators import * from lldbsuite.test.lldbtest import * from lldbsuite.test.lldbdwarf import * class TestGdbRemote_qMemoryRegion(gdbremote_testcase.GdbRemoteTestCaseBase): def test_qRegisterInfo_returns_one_valid_result(self): self.build() self.prep_debug_monitor_and_inferior() self.test_sequence.add_log_lines( [ "read packet: $qRegisterInfo0#00", { "direction": "send", "regex": r"^\$(.+);#[0-9A-Fa-f]{2}", "capture": {1: "reginfo_0"}, }, ], True, ) # Run the stream context = self.expect_gdbremote_sequence() self.assertIsNotNone(context) reg_info_packet = context.get("reginfo_0") self.assertIsNotNone(reg_info_packet) self.assert_valid_reg_info( lldbgdbserverutils.parse_reg_info_response(reg_info_packet) ) def test_qRegisterInfo_returns_all_valid_results(self): self.build() self.prep_debug_monitor_and_inferior() self.add_register_info_collection_packets() # Run the stream. context = self.expect_gdbremote_sequence() self.assertIsNotNone(context) # Validate that each register info returned validates. for reg_info in self.parse_register_info_packets(context): self.assert_valid_reg_info(reg_info) def test_qRegisterInfo_contains_required_generics_debugserver(self): self.build() self.prep_debug_monitor_and_inferior() self.add_register_info_collection_packets() # Run the packet stream. context = self.expect_gdbremote_sequence() self.assertIsNotNone(context) # Gather register info entries. reg_infos = self.parse_register_info_packets(context) # Collect all generic registers found. generic_regs = { reg_info["generic"]: 1 for reg_info in reg_infos if "generic" in reg_info } # Ensure we have a program counter register. self.assertIn("pc", generic_regs) # Ensure we have a frame pointer register. PPC64le's FP is the same as SP if self.getArchitecture() != "powerpc64le": self.assertIn("fp", generic_regs) # Ensure we have a stack pointer register. self.assertIn("sp", generic_regs) # Ensure we have a flags register. RISC-V doesn't have a flags register if not self.isRISCV(): self.assertIn("flags", generic_regs) if self.isRISCV() or self.isAArch64() or self.isARM(): # Specific register for a return address self.assertIn("ra", generic_regs) # Function arguments registers for i in range(1, 5 if self.isARM() else 9): self.assertIn(f"arg{i}", generic_regs) def test_qRegisterInfo_contains_at_least_one_register_set(self): self.build() self.prep_debug_monitor_and_inferior() self.add_register_info_collection_packets() # Run the packet stream. context = self.expect_gdbremote_sequence() self.assertIsNotNone(context) # Gather register info entries. reg_infos = self.parse_register_info_packets(context) # Collect all register sets found. register_sets = { reg_info["set"]: 1 for reg_info in reg_infos if "set" in reg_info } self.assertGreaterEqual(len(register_sets), 1) def targetHasAVX(self): triple = self.dbg.GetSelectedPlatform().GetTriple() # TODO other platforms, please implement this function if not re.match(".*-.*-linux", triple): return True # Need to do something different for non-Linux/Android targets if lldb.remote_platform: self.runCmd('platform get-file "/proc/cpuinfo" "cpuinfo"') cpuinfo_path = "cpuinfo" self.addTearDownHook(lambda: os.unlink("cpuinfo")) else: cpuinfo_path = "/proc/cpuinfo" f = open(cpuinfo_path, "r") cpuinfo = f.read() f.close() return " avx " in cpuinfo @expectedFailureAll(oslist=["windows"]) # no avx for now. @skipIf(archs=no_match(["amd64", "i386", "x86_64"])) @add_test_categories(["llgs"]) def test_qRegisterInfo_contains_avx_registers(self): self.build() self.prep_debug_monitor_and_inferior() self.add_register_info_collection_packets() # Run the packet stream. context = self.expect_gdbremote_sequence() self.assertIsNotNone(context) # Gather register info entries. reg_infos = self.parse_register_info_packets(context) # Collect all generics found. register_sets = { reg_info["set"]: 1 for reg_info in reg_infos if "set" in reg_info } self.assertEqual( self.targetHasAVX(), "Advanced Vector Extensions" in register_sets )