| """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 |
| |
| |
| 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) |
| |
| # 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)) |