"""Test Python APIs for setting, getting, and using address masks."""

import os
import lldb
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil


@requireNotWasm("no ABI plugin, so address masks are never applied")
class AddressMasksTestCase(TestBase):
    NO_DEBUG_INFO_TESTCASE = True

    def reset_all_masks(self, process):
        process.SetAddressMask(
            lldb.eAddressMaskTypeAll,
            lldb.LLDB_INVALID_ADDRESS_MASK,
            lldb.eAddressMaskRangeAll,
        )
        self.runCmd("settings set target.process.virtual-addressable-bits 0")
        self.runCmd("settings set target.process.highmem-virtual-addressable-bits 0")

    @skipIf(archs=["arm$"])  # 32-bit arm ABI hardcodes Code mask, is 32-bit
    def test_address_masks(self):
        self.build()
        (target, process, t, bp) = lldbutil.run_to_source_breakpoint(
            self, "break here", lldb.SBFileSpec("main.c")
        )

        process.SetAddressableBits(lldb.eAddressMaskTypeAll, 42)
        self.assertEqual(0x0000029500003F94, process.FixAddress(0x00265E9500003F94))
        self.reset_all_masks(process)

        # ~((1ULL<<42)-1) == 0xfffffc0000000000
        process.SetAddressMask(lldb.eAddressMaskTypeAll, 0xFFFFFC0000000000)
        self.assertEqual(0x0000029500003F94, process.FixAddress(0x00265E9500003F94))
        self.reset_all_masks(process)

        # Check that all bits can pass through unmodified
        process.SetAddressableBits(lldb.eAddressMaskTypeAll, 64)
        self.assertEqual(0x00265E9500003F94, process.FixAddress(0x00265E9500003F94))
        self.reset_all_masks(process)

        process.SetAddressableBits(
            lldb.eAddressMaskTypeAll, 42, lldb.eAddressMaskRangeAll
        )
        self.assertEqual(0x000002950001F694, process.FixAddress(0x00265E950001F694))
        self.assertEqual(0xFFFFFE950000F694, process.FixAddress(0xFFA65E950000F694))
        self.reset_all_masks(process)

        # Set a eAddressMaskTypeCode which has the low 3 bits marked as non-address
        # bits, confirm that they're cleared by FixAddress.
        process.SetAddressableBits(
            lldb.eAddressMaskTypeAll, 42, lldb.eAddressMaskRangeAll
        )
        mask = process.GetAddressMask(lldb.eAddressMaskTypeAny)
        process.SetAddressMask(lldb.eAddressMaskTypeCode, mask | 0x3)
        self.assertEqual(0x000002950001F697, process.FixAddress(0x00265E950001F697))
        self.assertEqual(0xFFFFFE950000F697, process.FixAddress(0xFFA65E950000F697))
        self.assertEqual(
            0x000002950001F697,
            process.FixAddress(0x00265E950001F697, lldb.eAddressMaskTypeData),
        )
        self.assertEqual(
            0x000002950001F694,
            process.FixAddress(0x00265E950001F697, lldb.eAddressMaskTypeCode),
        )
        self.reset_all_masks(process)

        # The user can override whatever settings the Process thinks should be used.
        process.SetAddressableBits(
            lldb.eAddressMaskTypeAll, 42, lldb.eAddressMaskRangeLow
        )
        self.runCmd("settings set target.process.virtual-addressable-bits 15")
        self.assertEqual(0x0000000000007694, process.FixAddress(0x00265E950001F694))
        self.assertEqual(0xFFFFFFFFFFFFF694, process.FixAddress(0xFFA65E950000F694))
        self.runCmd("settings set target.process.virtual-addressable-bits 0")
        self.assertEqual(0x000002950001F694, process.FixAddress(0x00265E950001F694))
        self.reset_all_masks(process)

    # AArch64 can have different address masks for high and low memory, when different
    # page tables are set up.
    @skipIf(archs=no_match(["arm64", "arm64e", "aarch64"]))
    @skipIf(archs=["arm$"])  # 32-bit arm ABI hardcodes Code mask, is 32-bit
    def test_address_masks_target_supports_highmem_tests(self):
        self.build()
        (target, process, t, bp) = lldbutil.run_to_source_breakpoint(
            self, "break here", lldb.SBFileSpec("main.c")
        )

        process.SetAddressableBits(
            lldb.eAddressMaskTypeAll, 42, lldb.eAddressMaskRangeLow
        )
        process.SetAddressableBits(
            lldb.eAddressMaskTypeAll, 15, lldb.eAddressMaskRangeHigh
        )
        self.assertEqual(0x000002950001F694, process.FixAddress(0x00265E950001F694))
        self.assertEqual(0xFFFFFFFFFFFFF694, process.FixAddress(0xFFA65E950000F694))
        self.reset_all_masks(process)

        # The user can override whatever settings the Process thinks should be used.
        process.SetAddressableBits(
            lldb.eAddressMaskTypeAll, 42, lldb.eAddressMaskRangeAll
        )
        self.runCmd("settings set target.process.virtual-addressable-bits 15")
        self.runCmd("settings set target.process.highmem-virtual-addressable-bits 15")
        self.assertEqual(0x0000000000007694, process.FixAddress(0x00265E950001F694))
        self.assertEqual(0xFFFFFFFFFFFFF694, process.FixAddress(0xFFA65E950000F694))
        self.runCmd("settings set target.process.virtual-addressable-bits 0")
        self.runCmd("settings set target.process.highmem-virtual-addressable-bits 0")
        self.assertEqual(0x000002950001F694, process.FixAddress(0x00265E950001F694))
        self.reset_all_masks(process)

    @skipIf(archs=no_match(["arm64", "arm64e", "aarch64"]))
    def test_changing_mask_invalidates_stack_frames(self):
        self.build()
        (target, process, thread, bp) = lldbutil.run_to_source_breakpoint(
            self, "break here", lldb.SBFileSpec("main.c")
        )

        pc = thread.GetFrameAtIndex(0).GetPC()
        self.assertNotEqual(pc & ~0x7FFF, 0)

        process.SetAddressableBits(lldb.eAddressMaskTypeAll, 15)
        self.assertEqual(thread.GetFrameAtIndex(0).GetPC(), pc & 0x7FFF)

        process.SetAddressableBits(lldb.eAddressMaskTypeAll, 64)
        self.assertEqual(thread.GetFrameAtIndex(0).GetPC(), pc)

        self.runCmd("settings set target.process.virtual-addressable-bits 15")
        self.assertEqual(thread.GetFrameAtIndex(0).GetPC(), pc & 0x7FFF)

        self.reset_all_masks(process)
        self.assertEqual(thread.GetFrameAtIndex(0).GetPC(), pc)

    # On most targets where we have a single mask for all address range, confirm
    # that the high memory masks are ignored.
    @skipIf(archs=["arm64", "arm64e", "aarch64"])
    @skipIf(archs=["arm$"])  # 32-bit arm ABI hardcodes Code mask, is 32-bit
    def test_address_masks_target_no_highmem(self):
        self.build()
        (target, process, t, bp) = lldbutil.run_to_source_breakpoint(
            self, "break here", lldb.SBFileSpec("main.c")
        )

        process.SetAddressableBits(
            lldb.eAddressMaskTypeAll, 42, lldb.eAddressMaskRangeLow
        )
        process.SetAddressableBits(
            lldb.eAddressMaskTypeAll, 15, lldb.eAddressMaskRangeHigh
        )
        self.assertEqual(0x000002950001F694, process.FixAddress(0x00265E950001F694))
        self.assertEqual(0xFFFFFE950000F694, process.FixAddress(0xFFA65E950000F694))
        self.runCmd("settings set target.process.virtual-addressable-bits 15")
        self.runCmd("settings set target.process.highmem-virtual-addressable-bits 42")
        self.assertEqual(0x0000000000007694, process.FixAddress(0x00265E950001F694))
        self.assertEqual(0xFFFFFFFFFFFFF694, process.FixAddress(0xFFA65E950000F694))
