[lldb] Address mask sbprocess apis and new mask invalid const (#83663)
[lldb] Add SBProcess methods for get/set/use address masks (#83095)
I'm reviving a patch from phabracator, https://reviews.llvm.org/D155905
which was approved but I wasn't thrilled with all the API I was adding
to SBProcess for all of the address mask types / memory regions. In this
update, I added enums to control type address mask type (code, data,
any) and address space specifiers (low, high, all) with defaulted
arguments for the most common case. I originally landed this via
https://github.com/llvm/llvm-project/pull/83095 but it failed on CIs
outside of arm64 Darwin so I had to debug it on more environments
and update the patch.
This patch is also fixing a bug in the "addressable bits to address
mask" calculation I added in AddressableBits::SetProcessMasks. If lldb
were told that 64 bits are valid for addressing, this method would
overflow the calculation and set an invalid mask. Added tests to check
this specific bug while I was adding these APIs.
This patch changes the value of "no mask set" from 0 to
LLDB_INVALID_ADDRESS_MASK, which is UINT64_MAX. A mask of all 1's
means "no bits are used for addressing" which is an impossible mask,
whereas a mask of 0 means "all bits are used for addressing" which
is possible.
I added a base class implementation of ABI::FixCodeAddress and
ABI::FixDataAddress that will apply the Process mask values if they
are set to a value other than LLDB_INVALID_ADDRESS_MASK.
I updated all the callers/users of the Mask methods which were
handling a value of 0 to mean invalid mask to use
LLDB_INVALID_ADDRESS_MASK.
I added code to the all AArch64 ABI Fix* methods to apply the
Highmem masks if they have been set. These will not be set on a
Linux environment, but in TestAddressMasks.py I test the highmem
masks feature for any AArch64 target, so all AArch64 ABI plugins
must handle it.
rdar://123530562
2024-03-06 10:06:56 -08:00
|
|
|
"""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")
|
|
|
|
|
2024-03-06 10:53:37 -08:00
|
|
|
@skipIf(archs=["arm"]) # 32-bit arm ABI hardcodes Code mask, is 32-bit
|
[lldb] Address mask sbprocess apis and new mask invalid const (#83663)
[lldb] Add SBProcess methods for get/set/use address masks (#83095)
I'm reviving a patch from phabracator, https://reviews.llvm.org/D155905
which was approved but I wasn't thrilled with all the API I was adding
to SBProcess for all of the address mask types / memory regions. In this
update, I added enums to control type address mask type (code, data,
any) and address space specifiers (low, high, all) with defaulted
arguments for the most common case. I originally landed this via
https://github.com/llvm/llvm-project/pull/83095 but it failed on CIs
outside of arm64 Darwin so I had to debug it on more environments
and update the patch.
This patch is also fixing a bug in the "addressable bits to address
mask" calculation I added in AddressableBits::SetProcessMasks. If lldb
were told that 64 bits are valid for addressing, this method would
overflow the calculation and set an invalid mask. Added tests to check
this specific bug while I was adding these APIs.
This patch changes the value of "no mask set" from 0 to
LLDB_INVALID_ADDRESS_MASK, which is UINT64_MAX. A mask of all 1's
means "no bits are used for addressing" which is an impossible mask,
whereas a mask of 0 means "all bits are used for addressing" which
is possible.
I added a base class implementation of ABI::FixCodeAddress and
ABI::FixDataAddress that will apply the Process mask values if they
are set to a value other than LLDB_INVALID_ADDRESS_MASK.
I updated all the callers/users of the Mask methods which were
handling a value of 0 to mean invalid mask to use
LLDB_INVALID_ADDRESS_MASK.
I added code to the all AArch64 ABI Fix* methods to apply the
Highmem masks if they have been set. These will not be set on a
Linux environment, but in TestAddressMasks.py I test the highmem
masks feature for any AArch64 target, so all AArch64 ABI plugins
must handle it.
rdar://123530562
2024-03-06 10:06:56 -08:00
|
|
|
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"]))
|
2024-03-06 10:53:37 -08:00
|
|
|
@skipIf(archs=["arm"]) # 32-bit arm ABI hardcodes Code mask, is 32-bit
|
[lldb] Address mask sbprocess apis and new mask invalid const (#83663)
[lldb] Add SBProcess methods for get/set/use address masks (#83095)
I'm reviving a patch from phabracator, https://reviews.llvm.org/D155905
which was approved but I wasn't thrilled with all the API I was adding
to SBProcess for all of the address mask types / memory regions. In this
update, I added enums to control type address mask type (code, data,
any) and address space specifiers (low, high, all) with defaulted
arguments for the most common case. I originally landed this via
https://github.com/llvm/llvm-project/pull/83095 but it failed on CIs
outside of arm64 Darwin so I had to debug it on more environments
and update the patch.
This patch is also fixing a bug in the "addressable bits to address
mask" calculation I added in AddressableBits::SetProcessMasks. If lldb
were told that 64 bits are valid for addressing, this method would
overflow the calculation and set an invalid mask. Added tests to check
this specific bug while I was adding these APIs.
This patch changes the value of "no mask set" from 0 to
LLDB_INVALID_ADDRESS_MASK, which is UINT64_MAX. A mask of all 1's
means "no bits are used for addressing" which is an impossible mask,
whereas a mask of 0 means "all bits are used for addressing" which
is possible.
I added a base class implementation of ABI::FixCodeAddress and
ABI::FixDataAddress that will apply the Process mask values if they
are set to a value other than LLDB_INVALID_ADDRESS_MASK.
I updated all the callers/users of the Mask methods which were
handling a value of 0 to mean invalid mask to use
LLDB_INVALID_ADDRESS_MASK.
I added code to the all AArch64 ABI Fix* methods to apply the
Highmem masks if they have been set. These will not be set on a
Linux environment, but in TestAddressMasks.py I test the highmem
masks feature for any AArch64 target, so all AArch64 ABI plugins
must handle it.
rdar://123530562
2024-03-06 10:06:56 -08:00
|
|
|
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"])
|
2024-03-06 10:53:37 -08:00
|
|
|
@skipIf(archs=["arm"]) # 32-bit arm ABI hardcodes Code mask, is 32-bit
|
[lldb] Address mask sbprocess apis and new mask invalid const (#83663)
[lldb] Add SBProcess methods for get/set/use address masks (#83095)
I'm reviving a patch from phabracator, https://reviews.llvm.org/D155905
which was approved but I wasn't thrilled with all the API I was adding
to SBProcess for all of the address mask types / memory regions. In this
update, I added enums to control type address mask type (code, data,
any) and address space specifiers (low, high, all) with defaulted
arguments for the most common case. I originally landed this via
https://github.com/llvm/llvm-project/pull/83095 but it failed on CIs
outside of arm64 Darwin so I had to debug it on more environments
and update the patch.
This patch is also fixing a bug in the "addressable bits to address
mask" calculation I added in AddressableBits::SetProcessMasks. If lldb
were told that 64 bits are valid for addressing, this method would
overflow the calculation and set an invalid mask. Added tests to check
this specific bug while I was adding these APIs.
This patch changes the value of "no mask set" from 0 to
LLDB_INVALID_ADDRESS_MASK, which is UINT64_MAX. A mask of all 1's
means "no bits are used for addressing" which is an impossible mask,
whereas a mask of 0 means "all bits are used for addressing" which
is possible.
I added a base class implementation of ABI::FixCodeAddress and
ABI::FixDataAddress that will apply the Process mask values if they
are set to a value other than LLDB_INVALID_ADDRESS_MASK.
I updated all the callers/users of the Mask methods which were
handling a value of 0 to mean invalid mask to use
LLDB_INVALID_ADDRESS_MASK.
I added code to the all AArch64 ABI Fix* methods to apply the
Highmem masks if they have been set. These will not be set on a
Linux environment, but in TestAddressMasks.py I test the highmem
masks feature for any AArch64 target, so all AArch64 ABI plugins
must handle it.
rdar://123530562
2024-03-06 10:06:56 -08:00
|
|
|
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))
|