1import xml.etree.ElementTree as ET 2import gdbremote_testcase 3from lldbsuite.test.decorators import * 4from lldbsuite.test.lldbtest import * 5 6 7# Windows does not allow quotes in file names. 8@skipIf(hostoslist=["windows"]) 9@skipIfRemote 10class TestGdbRemoteLibrariesSvr4Support(gdbremote_testcase.GdbRemoteTestCaseBase): 11 FEATURE_NAME = "qXfer:libraries-svr4:read" 12 13 def setup_test(self): 14 self.build() 15 self.set_inferior_startup_launch() 16 env = {} 17 env[self.dylibPath] = self.getBuildDir() 18 self.prep_debug_monitor_and_inferior(inferior_env=env) 19 self.continue_process_and_wait_for_stop() 20 21 def get_expected_libs(self): 22 return ["libsvr4lib_a.so", 'libsvr4lib_b".so'] 23 24 def has_libraries_svr4_support(self): 25 self.add_qSupported_packets() 26 context = self.expect_gdbremote_sequence() 27 self.assertIsNotNone(context) 28 features = self.parse_qSupported_response(context) 29 return self.FEATURE_NAME in features and features[self.FEATURE_NAME] == "+" 30 31 def get_libraries_svr4_data(self): 32 # Start up llgs and inferior, and check for libraries-svr4 support. 33 if not self.has_libraries_svr4_support(): 34 self.skipTest("libraries-svr4 not supported") 35 36 # Grab the libraries-svr4 data. 37 self.reset_test_sequence() 38 self.test_sequence.add_log_lines( 39 [ 40 "read packet: $qXfer:libraries-svr4:read::0,ffff:#00", 41 { 42 "direction": "send", 43 "regex": re.compile( 44 r"^\$([^E])(.*)#[0-9a-fA-F]{2}$", re.MULTILINE | re.DOTALL 45 ), 46 "capture": {1: "response_type", 2: "content_raw"}, 47 }, 48 ], 49 True, 50 ) 51 52 context = self.expect_gdbremote_sequence() 53 self.assertIsNotNone(context) 54 55 # Ensure we end up with all libraries-svr4 data in one packet. 56 self.assertEqual(context.get("response_type"), "l") 57 58 # Decode binary data. 59 content_raw = context.get("content_raw") 60 self.assertIsNotNone(content_raw) 61 return content_raw 62 63 def get_libraries_svr4_xml(self): 64 libraries_svr4 = self.get_libraries_svr4_data() 65 xml_root = None 66 try: 67 xml_root = ET.fromstring(libraries_svr4) 68 except xml.etree.ElementTree.ParseError: 69 pass 70 self.assertIsNotNone(xml_root, "Malformed libraries-svr4 XML") 71 return xml_root 72 73 def libraries_svr4_well_formed(self): 74 xml_root = self.get_libraries_svr4_xml() 75 self.assertEqual(xml_root.tag, "library-list-svr4") 76 for child in xml_root: 77 self.assertEqual(child.tag, "library") 78 self.assertCountEqual(child.attrib.keys(), ["name", "lm", "l_addr", "l_ld"]) 79 80 def libraries_svr4_has_correct_load_addr(self): 81 xml_root = self.get_libraries_svr4_xml() 82 for child in xml_root: 83 name = child.attrib.get("name") 84 base_name = os.path.basename(name) 85 if os.path.basename(name) not in self.get_expected_libs(): 86 continue 87 load_addr = int(child.attrib.get("l_addr"), 16) 88 self.reset_test_sequence() 89 self.add_query_memory_region_packets(load_addr) 90 context = self.expect_gdbremote_sequence() 91 mem_region = self.parse_memory_region_packet(context) 92 self.assertEqual(load_addr, int(mem_region.get("start", 0), 16)) 93 self.assertEqual( 94 os.path.realpath(name), os.path.realpath(mem_region.get("name", "")) 95 ) 96 97 def libraries_svr4_libs_present(self): 98 xml_root = self.get_libraries_svr4_xml() 99 libraries_svr4_names = [] 100 for child in xml_root: 101 name = child.attrib.get("name") 102 libraries_svr4_names.append(os.path.realpath(name)) 103 for lib in self.get_expected_libs(): 104 self.assertIn( 105 os.path.realpath(self.getBuildDir() + "/" + lib), libraries_svr4_names 106 ) 107 108 @skipUnlessPlatform(["linux", "android", "freebsd", "netbsd"]) 109 def test_supports_libraries_svr4(self): 110 self.setup_test() 111 self.assertTrue(self.has_libraries_svr4_support()) 112 113 @skipUnlessPlatform(["linux", "android", "freebsd", "netbsd"]) 114 @expectedFailureNetBSD 115 def test_libraries_svr4_well_formed(self): 116 self.setup_test() 117 self.libraries_svr4_well_formed() 118 119 @skipUnlessPlatform(["linux", "android", "freebsd", "netbsd"]) 120 @expectedFailureNetBSD 121 def test_libraries_svr4_load_addr(self): 122 self.setup_test() 123 self.libraries_svr4_has_correct_load_addr() 124 125 @skipUnlessPlatform(["linux", "android", "freebsd", "netbsd"]) 126 @expectedFailureNetBSD 127 def test_libraries_svr4_libs_present(self): 128 self.setup_test() 129 self.libraries_svr4_libs_present() 130