import lldb
from lldbsuite.test.lldbtest import *
from lldbsuite.test.decorators import *
from lldbsuite.test.gdbclientutils import *
from lldbsuite.test.lldbgdbclient import GDBRemoteTestBase


class MyResponder(MockGDBServerResponder):
    """
    A responder which simulates a process with a single shared library loaded.
    Its parameters allow configuration of various properties of the library.
    """

    def __init__(self, testcase, triple, library_name, auxv_entry, region_info):
        MockGDBServerResponder.__init__(self)
        self.testcase = testcase
        self._triple = triple
        self._library_name = library_name
        self._auxv_entry = auxv_entry
        self._region_info = region_info

    def qSupported(self, client_supported):
        return (
            super().qSupported(client_supported)
            + ";qXfer:auxv:read+;qXfer:libraries-svr4:read+"
        )

    def qXferRead(self, obj, annex, offset, length):
        if obj == "features" and annex == "target.xml":
            return (
                """<?xml version="1.0"?>
                <target version="1.0">
                  <architecture>i386:x86-64</architecture>
                  <feature name="org.gnu.gdb.i386.core">
                    <reg name="rip" bitsize="64" regnum="0" type="code_ptr" group="general"/>
                  </feature>
                </target>""",
                False,
            )
        elif obj == "auxv":
            # 0x09 = AT_ENTRY, which lldb uses to compute the load bias of the
            # main binary.
            return (
                hex_decode_bytes(
                    self._auxv_entry
                    + "09000000000000000000ee000000000000000000000000000000000000000000"
                ),
                False,
            )
        elif obj == "libraries-svr4":
            return (
                """<?xml version="1.0"?>
                <library-list-svr4 version="1.0">
                  <library name="%s" lm="0xdeadbeef" l_addr="0xef0000" l_ld="0xdeadbeef"/>
                </library-list-svr4>"""
                % self._library_name,
                False,
            )
        else:
            return None, False

    def qsThreadInfo(self):
        return "l"

    # In the two following functions, we return a PID == PID_MAX_LIMIT so that we do not
    # use a host program file. Note that the number is in hex.
    PID_MAX_LIMIT = "400000"

    def qfThreadInfo(self):
        return f"m{self.PID_MAX_LIMIT}"

    def qProcessInfo(self):
        return "pid:%s;ptrsize:8;endian:little;triple:%s;" % (
            self.PID_MAX_LIMIT,
            hex_encode_bytes(self._triple),
        )

    def setBreakpoint(self, packet):
        return "OK"

    def readMemory(self, addr, length):
        if addr == 0xEE1000:
            return "00" * 0x30 + "0020ee0000000000"
        elif addr == 0xEE2000:
            return "01000000000000000030ee0000000000dead00000000000000000000000000000000000000000000"
        elif addr == 0xEF0000:
            with open(self.testcase.getBuildArtifact("libmodule_load.so"), "rb") as f:
                contents = f.read(-1)
            return hex_encode_bytes(seven.bitcast_to_string(contents))
        return ("baadf00d00" * 1000)[0 : length * 2]

    def qMemoryRegionInfo(self, addr):
        if addr < 0xEE0000:
            return "start:0;size:ee0000;"
        elif addr < 0xEF0000:
            return "start:ee0000;size:10000;"
        elif addr < 0xF00000:
            return "start:ef0000;size:1000;permissions:rx;" + self._region_info
        else:
            return "start:ef1000;size:ffffffffff10f000"


class TestGdbClientModuleLoad(GDBRemoteTestBase):
    @skipIfXmlSupportMissing
    def test_android_app_process(self):
        """
        This test simulates the scenario where the (android) dynamic linker
        reports incorrect file name of the main executable. Lldb uses
        qMemoryRegionInfo to get the correct value.
        """
        region_info = "name:%s;" % (
            hex_encode_bytes(self.getBuildArtifact("libmodule_load.so"))
        )
        self.server.responder = MyResponder(
            self, "x86_64-pc-linux-android", "bogus-name", "", region_info
        )
        self.yaml2obj("module_load.yaml", self.getBuildArtifact("libmodule_load.so"))
        target = self.createTarget("module_load.yaml")

        process = self.connect(target)
        self.assertTrue(process.IsValid(), "Process is valid")

        lldbutil.expect_state_changes(
            self, self.dbg.GetListener(), process, [lldb.eStateStopped]
        )

        self.filecheck("image list", __file__, "-check-prefix=ANDROID")

    # ANDROID: [  0] {{.*}} 0x0000000000ee0000 {{.*}}module_load
    # ANDROID: [  1] {{.*}} 0x0000000000ef0000 {{.*}}libmodule_load.so

    @skipIfXmlSupportMissing
    def test_vdso(self):
        """
        This test checks vdso loading in the situation where the process does
        not have memory region information about the vdso address. This can
        happen in core files, as they don't store this data.
        We want to check that the vdso is loaded exactly once.
        """
        # vdso address
        AT_SYSINFO_EHDR = "21000000000000000000ef0000000000"
        self.server.responder = MyResponder(
            self, "x86_64-pc-linux", "linux-vdso.so.1", AT_SYSINFO_EHDR, ""
        )
        self.yaml2obj("module_load.yaml", self.getBuildArtifact("libmodule_load.so"))
        target = self.createTarget("module_load.yaml")

        process = self.connect(target)
        self.assertTrue(process.IsValid(), "Process is valid")

        lldbutil.expect_state_changes(
            self, self.dbg.GetListener(), process, [lldb.eStateStopped]
        )

        self.filecheck("image list", __file__, "-check-prefix=VDSO")
        # VDSO: [  0] {{.*}} 0x0000000000ee0000 {{.*}}module_load
        # VDSO: [  1] {{.*}} 0x0000000000ef0000 {{.*}}[vdso]
        self.assertEqual(self.target().GetNumModules(), 2)
