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