xref: /llvm-project/lldb/test/API/tools/lldb-server/libraries-svr4/TestGdbRemoteLibrariesSvr4Support.py (revision facb767e5b78a024d70585b24254c769473b6b54)
199451b44SJordan Rupprechtimport xml.etree.ElementTree as ET
299451b44SJordan Rupprechtimport gdbremote_testcase
399451b44SJordan Rupprechtfrom lldbsuite.test.decorators import *
499451b44SJordan Rupprechtfrom lldbsuite.test.lldbtest import *
599451b44SJordan Rupprecht
699451b44SJordan Rupprecht
72bc9af96SDmitry Vasilyev# Windows does not allow quotes in file names.
82bc9af96SDmitry Vasilyev@skipIf(hostoslist=["windows"])
9*facb767eSDmitry Vasilyev@skipIfRemote
102238dcc3SJonas Devlieghereclass TestGdbRemoteLibrariesSvr4Support(gdbremote_testcase.GdbRemoteTestCaseBase):
1199451b44SJordan Rupprecht    FEATURE_NAME = "qXfer:libraries-svr4:read"
1299451b44SJordan Rupprecht
1399451b44SJordan Rupprecht    def setup_test(self):
1499451b44SJordan Rupprecht        self.build()
1599451b44SJordan Rupprecht        self.set_inferior_startup_launch()
1699451b44SJordan Rupprecht        env = {}
1799451b44SJordan Rupprecht        env[self.dylibPath] = self.getBuildDir()
1899451b44SJordan Rupprecht        self.prep_debug_monitor_and_inferior(inferior_env=env)
1999451b44SJordan Rupprecht        self.continue_process_and_wait_for_stop()
2099451b44SJordan Rupprecht
2199451b44SJordan Rupprecht    def get_expected_libs(self):
2299451b44SJordan Rupprecht        return ["libsvr4lib_a.so", 'libsvr4lib_b".so']
2399451b44SJordan Rupprecht
2499451b44SJordan Rupprecht    def has_libraries_svr4_support(self):
2599451b44SJordan Rupprecht        self.add_qSupported_packets()
2699451b44SJordan Rupprecht        context = self.expect_gdbremote_sequence()
2799451b44SJordan Rupprecht        self.assertIsNotNone(context)
2899451b44SJordan Rupprecht        features = self.parse_qSupported_response(context)
2999451b44SJordan Rupprecht        return self.FEATURE_NAME in features and features[self.FEATURE_NAME] == "+"
3099451b44SJordan Rupprecht
3199451b44SJordan Rupprecht    def get_libraries_svr4_data(self):
3299451b44SJordan Rupprecht        # Start up llgs and inferior, and check for libraries-svr4 support.
3399451b44SJordan Rupprecht        if not self.has_libraries_svr4_support():
3499451b44SJordan Rupprecht            self.skipTest("libraries-svr4 not supported")
3599451b44SJordan Rupprecht
3699451b44SJordan Rupprecht        # Grab the libraries-svr4 data.
3799451b44SJordan Rupprecht        self.reset_test_sequence()
3899451b44SJordan Rupprecht        self.test_sequence.add_log_lines(
3999451b44SJordan Rupprecht            [
4099451b44SJordan Rupprecht                "read packet: $qXfer:libraries-svr4:read::0,ffff:#00",
4199451b44SJordan Rupprecht                {
4299451b44SJordan Rupprecht                    "direction": "send",
4399451b44SJordan Rupprecht                    "regex": re.compile(
4499451b44SJordan Rupprecht                        r"^\$([^E])(.*)#[0-9a-fA-F]{2}$", re.MULTILINE | re.DOTALL
4599451b44SJordan Rupprecht                    ),
4699451b44SJordan Rupprecht                    "capture": {1: "response_type", 2: "content_raw"},
4799451b44SJordan Rupprecht                },
4899451b44SJordan Rupprecht            ],
4999451b44SJordan Rupprecht            True,
5099451b44SJordan Rupprecht        )
5199451b44SJordan Rupprecht
5299451b44SJordan Rupprecht        context = self.expect_gdbremote_sequence()
5399451b44SJordan Rupprecht        self.assertIsNotNone(context)
5499451b44SJordan Rupprecht
5599451b44SJordan Rupprecht        # Ensure we end up with all libraries-svr4 data in one packet.
5699451b44SJordan Rupprecht        self.assertEqual(context.get("response_type"), "l")
5799451b44SJordan Rupprecht
5899451b44SJordan Rupprecht        # Decode binary data.
5999451b44SJordan Rupprecht        content_raw = context.get("content_raw")
6099451b44SJordan Rupprecht        self.assertIsNotNone(content_raw)
6199451b44SJordan Rupprecht        return content_raw
6299451b44SJordan Rupprecht
6399451b44SJordan Rupprecht    def get_libraries_svr4_xml(self):
6499451b44SJordan Rupprecht        libraries_svr4 = self.get_libraries_svr4_data()
6599451b44SJordan Rupprecht        xml_root = None
6699451b44SJordan Rupprecht        try:
6799451b44SJordan Rupprecht            xml_root = ET.fromstring(libraries_svr4)
6899451b44SJordan Rupprecht        except xml.etree.ElementTree.ParseError:
6999451b44SJordan Rupprecht            pass
7099451b44SJordan Rupprecht        self.assertIsNotNone(xml_root, "Malformed libraries-svr4 XML")
7199451b44SJordan Rupprecht        return xml_root
7299451b44SJordan Rupprecht
7399451b44SJordan Rupprecht    def libraries_svr4_well_formed(self):
7499451b44SJordan Rupprecht        xml_root = self.get_libraries_svr4_xml()
7599451b44SJordan Rupprecht        self.assertEqual(xml_root.tag, "library-list-svr4")
7699451b44SJordan Rupprecht        for child in xml_root:
7799451b44SJordan Rupprecht            self.assertEqual(child.tag, "library")
785b386158SJordan Rupprecht            self.assertCountEqual(child.attrib.keys(), ["name", "lm", "l_addr", "l_ld"])
7999451b44SJordan Rupprecht
8099451b44SJordan Rupprecht    def libraries_svr4_has_correct_load_addr(self):
8199451b44SJordan Rupprecht        xml_root = self.get_libraries_svr4_xml()
8299451b44SJordan Rupprecht        for child in xml_root:
8399451b44SJordan Rupprecht            name = child.attrib.get("name")
8499451b44SJordan Rupprecht            base_name = os.path.basename(name)
8599451b44SJordan Rupprecht            if os.path.basename(name) not in self.get_expected_libs():
8699451b44SJordan Rupprecht                continue
8799451b44SJordan Rupprecht            load_addr = int(child.attrib.get("l_addr"), 16)
8899451b44SJordan Rupprecht            self.reset_test_sequence()
8999451b44SJordan Rupprecht            self.add_query_memory_region_packets(load_addr)
9099451b44SJordan Rupprecht            context = self.expect_gdbremote_sequence()
9199451b44SJordan Rupprecht            mem_region = self.parse_memory_region_packet(context)
9299451b44SJordan Rupprecht            self.assertEqual(load_addr, int(mem_region.get("start", 0), 16))
9399451b44SJordan Rupprecht            self.assertEqual(
9499451b44SJordan Rupprecht                os.path.realpath(name), os.path.realpath(mem_region.get("name", ""))
9599451b44SJordan Rupprecht            )
9699451b44SJordan Rupprecht
9799451b44SJordan Rupprecht    def libraries_svr4_libs_present(self):
9899451b44SJordan Rupprecht        xml_root = self.get_libraries_svr4_xml()
9999451b44SJordan Rupprecht        libraries_svr4_names = []
10099451b44SJordan Rupprecht        for child in xml_root:
10199451b44SJordan Rupprecht            name = child.attrib.get("name")
10299451b44SJordan Rupprecht            libraries_svr4_names.append(os.path.realpath(name))
10399451b44SJordan Rupprecht        for lib in self.get_expected_libs():
1042238dcc3SJonas Devlieghere            self.assertIn(
1052238dcc3SJonas Devlieghere                os.path.realpath(self.getBuildDir() + "/" + lib), libraries_svr4_names
1062238dcc3SJonas Devlieghere            )
10799451b44SJordan Rupprecht
1082c2eb5e6SMichał Górny    @skipUnlessPlatform(["linux", "android", "freebsd", "netbsd"])
10999451b44SJordan Rupprecht    def test_supports_libraries_svr4(self):
11099451b44SJordan Rupprecht        self.setup_test()
11199451b44SJordan Rupprecht        self.assertTrue(self.has_libraries_svr4_support())
11299451b44SJordan Rupprecht
1132c2eb5e6SMichał Górny    @skipUnlessPlatform(["linux", "android", "freebsd", "netbsd"])
11499451b44SJordan Rupprecht    @expectedFailureNetBSD
11599451b44SJordan Rupprecht    def test_libraries_svr4_well_formed(self):
11699451b44SJordan Rupprecht        self.setup_test()
11799451b44SJordan Rupprecht        self.libraries_svr4_well_formed()
11899451b44SJordan Rupprecht
1192c2eb5e6SMichał Górny    @skipUnlessPlatform(["linux", "android", "freebsd", "netbsd"])
1208666b905SMichał Górny    @expectedFailureNetBSD
12199451b44SJordan Rupprecht    def test_libraries_svr4_load_addr(self):
12299451b44SJordan Rupprecht        self.setup_test()
12399451b44SJordan Rupprecht        self.libraries_svr4_has_correct_load_addr()
12499451b44SJordan Rupprecht
1252c2eb5e6SMichał Górny    @skipUnlessPlatform(["linux", "android", "freebsd", "netbsd"])
12699451b44SJordan Rupprecht    @expectedFailureNetBSD
12799451b44SJordan Rupprecht    def test_libraries_svr4_libs_present(self):
12899451b44SJordan Rupprecht        self.setup_test()
12999451b44SJordan Rupprecht        self.libraries_svr4_libs_present()
130