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