xref: /llvm-project/lldb/test/API/functionalities/gdb_remote_client/TestGdbClientModuleLoad.py (revision 80fcecb13c388ff087a27a4b0e7ca3dd8c98eaa4)
1e67cee09SPavel Labathimport lldb
2e67cee09SPavel Labathfrom lldbsuite.test.lldbtest import *
3e67cee09SPavel Labathfrom lldbsuite.test.decorators import *
4e67cee09SPavel Labathfrom lldbsuite.test.gdbclientutils import *
5e67cee09SPavel Labathfrom lldbsuite.test.lldbgdbclient import GDBRemoteTestBase
6e67cee09SPavel Labath
72238dcc3SJonas Devlieghere
8e67cee09SPavel Labathclass MyResponder(MockGDBServerResponder):
9e67cee09SPavel Labath    """
10e67cee09SPavel Labath    A responder which simulates a process with a single shared library loaded.
11e67cee09SPavel Labath    Its parameters allow configuration of various properties of the library.
12e67cee09SPavel Labath    """
13e67cee09SPavel Labath
14e67cee09SPavel Labath    def __init__(self, testcase, triple, library_name, auxv_entry, region_info):
15e67cee09SPavel Labath        MockGDBServerResponder.__init__(self)
16e67cee09SPavel Labath        self.testcase = testcase
17e67cee09SPavel Labath        self._triple = triple
18e67cee09SPavel Labath        self._library_name = library_name
19e67cee09SPavel Labath        self._auxv_entry = auxv_entry
20e67cee09SPavel Labath        self._region_info = region_info
21e67cee09SPavel Labath
22e67cee09SPavel Labath    def qSupported(self, client_supported):
232238dcc3SJonas Devlieghere        return (
242238dcc3SJonas Devlieghere            super().qSupported(client_supported)
252238dcc3SJonas Devlieghere            + ";qXfer:auxv:read+;qXfer:libraries-svr4:read+"
262238dcc3SJonas Devlieghere        )
27e67cee09SPavel Labath
28e67cee09SPavel Labath    def qXferRead(self, obj, annex, offset, length):
29e67cee09SPavel Labath        if obj == "features" and annex == "target.xml":
302238dcc3SJonas Devlieghere            return (
312238dcc3SJonas Devlieghere                """<?xml version="1.0"?>
32e67cee09SPavel Labath                <target version="1.0">
33e67cee09SPavel Labath                  <architecture>i386:x86-64</architecture>
34e67cee09SPavel Labath                  <feature name="org.gnu.gdb.i386.core">
35e67cee09SPavel Labath                    <reg name="rip" bitsize="64" regnum="0" type="code_ptr" group="general"/>
36e67cee09SPavel Labath                  </feature>
372238dcc3SJonas Devlieghere                </target>""",
382238dcc3SJonas Devlieghere                False,
392238dcc3SJonas Devlieghere            )
40e67cee09SPavel Labath        elif obj == "auxv":
41e67cee09SPavel Labath            # 0x09 = AT_ENTRY, which lldb uses to compute the load bias of the
42e67cee09SPavel Labath            # main binary.
432238dcc3SJonas Devlieghere            return (
442238dcc3SJonas Devlieghere                hex_decode_bytes(
452238dcc3SJonas Devlieghere                    self._auxv_entry
462238dcc3SJonas Devlieghere                    + "09000000000000000000ee000000000000000000000000000000000000000000"
472238dcc3SJonas Devlieghere                ),
482238dcc3SJonas Devlieghere                False,
492238dcc3SJonas Devlieghere            )
50e67cee09SPavel Labath        elif obj == "libraries-svr4":
512238dcc3SJonas Devlieghere            return (
522238dcc3SJonas Devlieghere                """<?xml version="1.0"?>
53e67cee09SPavel Labath                <library-list-svr4 version="1.0">
54e67cee09SPavel Labath                  <library name="%s" lm="0xdeadbeef" l_addr="0xef0000" l_ld="0xdeadbeef"/>
552238dcc3SJonas Devlieghere                </library-list-svr4>"""
562238dcc3SJonas Devlieghere                % self._library_name,
572238dcc3SJonas Devlieghere                False,
582238dcc3SJonas Devlieghere            )
59e67cee09SPavel Labath        else:
60e67cee09SPavel Labath            return None, False
61e67cee09SPavel Labath
62e67cee09SPavel Labath    def qfThreadInfo(self):
63e67cee09SPavel Labath        return "m47"
64e67cee09SPavel Labath
65e67cee09SPavel Labath    def qsThreadInfo(self):
66e67cee09SPavel Labath        return "l"
67e67cee09SPavel Labath
68e67cee09SPavel Labath    def qProcessInfo(self):
692238dcc3SJonas Devlieghere        return "pid:47;ptrsize:8;endian:little;triple:%s;" % hex_encode_bytes(
702238dcc3SJonas Devlieghere            self._triple
712238dcc3SJonas Devlieghere        )
72e67cee09SPavel Labath
73e67cee09SPavel Labath    def setBreakpoint(self, packet):
74e67cee09SPavel Labath        return "OK"
75e67cee09SPavel Labath
76e67cee09SPavel Labath    def readMemory(self, addr, length):
772238dcc3SJonas Devlieghere        if addr == 0xEE1000:
78e67cee09SPavel Labath            return "00" * 0x30 + "0020ee0000000000"
792238dcc3SJonas Devlieghere        elif addr == 0xEE2000:
80e67cee09SPavel Labath            return "01000000000000000030ee0000000000dead00000000000000000000000000000000000000000000"
812238dcc3SJonas Devlieghere        elif addr == 0xEF0000:
82e67cee09SPavel Labath            with open(self.testcase.getBuildArtifact("libmodule_load.so"), "rb") as f:
83e67cee09SPavel Labath                contents = f.read(-1)
84e67cee09SPavel Labath            return hex_encode_bytes(seven.bitcast_to_string(contents))
85e67cee09SPavel Labath        return ("baadf00d00" * 1000)[0 : length * 2]
86e67cee09SPavel Labath
87e67cee09SPavel Labath    def qMemoryRegionInfo(self, addr):
882238dcc3SJonas Devlieghere        if addr < 0xEE0000:
89e67cee09SPavel Labath            return "start:0;size:ee0000;"
902238dcc3SJonas Devlieghere        elif addr < 0xEF0000:
91e67cee09SPavel Labath            return "start:ee0000;size:10000;"
922238dcc3SJonas Devlieghere        elif addr < 0xF00000:
93e67cee09SPavel Labath            return "start:ef0000;size:1000;permissions:rx;" + self._region_info
94e67cee09SPavel Labath        else:
95e67cee09SPavel Labath            return "start:ef1000;size:ffffffffff10f000"
96e67cee09SPavel Labath
97e67cee09SPavel Labath
982238dcc3SJonas Devlieghereclass TestGdbClientModuleLoad(GDBRemoteTestBase):
99e67cee09SPavel Labath    @skipIfXmlSupportMissing
100e67cee09SPavel Labath    def test_android_app_process(self):
101e67cee09SPavel Labath        """
102e67cee09SPavel Labath        This test simulates the scenario where the (android) dynamic linker
103e67cee09SPavel Labath        reports incorrect file name of the main executable. Lldb uses
104e67cee09SPavel Labath        qMemoryRegionInfo to get the correct value.
105e67cee09SPavel Labath        """
106e67cee09SPavel Labath        region_info = "name:%s;" % (
1072238dcc3SJonas Devlieghere            hex_encode_bytes(self.getBuildArtifact("libmodule_load.so"))
1082238dcc3SJonas Devlieghere        )
1092238dcc3SJonas Devlieghere        self.server.responder = MyResponder(
1102238dcc3SJonas Devlieghere            self, "x86_64-pc-linux-android", "bogus-name", "", region_info
1112238dcc3SJonas Devlieghere        )
112e67cee09SPavel Labath        self.yaml2obj("module_load.yaml", self.getBuildArtifact("libmodule_load.so"))
113e67cee09SPavel Labath        target = self.createTarget("module_load.yaml")
114e67cee09SPavel Labath
115e67cee09SPavel Labath        process = self.connect(target)
116e67cee09SPavel Labath        self.assertTrue(process.IsValid(), "Process is valid")
117e67cee09SPavel Labath
1182238dcc3SJonas Devlieghere        lldbutil.expect_state_changes(
1192238dcc3SJonas Devlieghere            self, self.dbg.GetListener(), process, [lldb.eStateStopped]
1202238dcc3SJonas Devlieghere        )
121e67cee09SPavel Labath
122e67cee09SPavel Labath        self.filecheck("image list", __file__, "-check-prefix=ANDROID")
1232238dcc3SJonas Devlieghere
124e67cee09SPavel Labath    # ANDROID: [  0] {{.*}} 0x0000000000ee0000 {{.*}}module_load
125e67cee09SPavel Labath    # ANDROID: [  1] {{.*}} 0x0000000000ef0000 {{.*}}libmodule_load.so
126e67cee09SPavel Labath
127e67cee09SPavel Labath    @skipIfXmlSupportMissing
128e67cee09SPavel Labath    def test_vdso(self):
129e67cee09SPavel Labath        """
130e67cee09SPavel Labath        This test checks vdso loading in the situation where the process does
131e67cee09SPavel Labath        not have memory region information about the vdso address. This can
132e67cee09SPavel Labath        happen in core files, as they don't store this data.
133e67cee09SPavel Labath        We want to check that the vdso is loaded exactly once.
134e67cee09SPavel Labath        """
135e67cee09SPavel Labath        # vdso address
136e67cee09SPavel Labath        AT_SYSINFO_EHDR = "21000000000000000000ef0000000000"
1372238dcc3SJonas Devlieghere        self.server.responder = MyResponder(
1382238dcc3SJonas Devlieghere            self, "x86_64-pc-linux", "linux-vdso.so.1", AT_SYSINFO_EHDR, ""
1392238dcc3SJonas Devlieghere        )
140e67cee09SPavel Labath        self.yaml2obj("module_load.yaml", self.getBuildArtifact("libmodule_load.so"))
141e67cee09SPavel Labath        target = self.createTarget("module_load.yaml")
142e67cee09SPavel Labath
143e67cee09SPavel Labath        process = self.connect(target)
144e67cee09SPavel Labath        self.assertTrue(process.IsValid(), "Process is valid")
145e67cee09SPavel Labath
1462238dcc3SJonas Devlieghere        lldbutil.expect_state_changes(
1472238dcc3SJonas Devlieghere            self, self.dbg.GetListener(), process, [lldb.eStateStopped]
1482238dcc3SJonas Devlieghere        )
149e67cee09SPavel Labath
150e67cee09SPavel Labath        self.filecheck("image list", __file__, "-check-prefix=VDSO")
151e67cee09SPavel Labath        # VDSO: [  0] {{.*}} 0x0000000000ee0000 {{.*}}module_load
152e67cee09SPavel Labath        # VDSO: [  1] {{.*}} 0x0000000000ef0000 {{.*}}[vdso]
153*80fcecb1SJonas Devlieghere        self.assertEqual(self.target().GetNumModules(), 2)
154