Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[lldb] Be conversative about setting highmem address masks #90533

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions lldb/include/lldb/Target/Process.h
Original file line number Diff line number Diff line change
Expand Up @@ -1465,6 +1465,20 @@ class Process : public std::enable_shared_from_this<Process>,
/// platforms where there is a difference (only Arm Thumb at this time).
lldb::addr_t FixAnyAddress(lldb::addr_t pc);

/// Retrieve the actual address masks for high memory code/data,
/// without the normal fallbacks of returning the low-memory masks
/// or the user settings. Needed by SBProcess to determine if
/// the high address masks have actually been set, and should
/// be updated when "set all masks" is requested. In most cases,
/// the highmem masks should be left to have LLDB_INVALID_ADDRESS_MASK,
/// unset.
lldb::addr_t GetConcreteHighmemCodeAddressMask() {
DavidSpickett marked this conversation as resolved.
Show resolved Hide resolved
return m_highmem_code_address_mask;
}
lldb::addr_t GetConcreteHighmemDataAddressMask() {
return m_highmem_data_address_mask;
}

/// Get the Modification ID of the process.
///
/// \return
Expand Down
26 changes: 22 additions & 4 deletions lldb/source/API/SBProcess.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1298,7 +1298,12 @@ void SBProcess::SetAddressMask(AddressMaskType type, addr_t mask,
case eAddressMaskTypeCode:
if (addr_range == eAddressMaskRangeAll) {
process_sp->SetCodeAddressMask(mask);
process_sp->SetHighmemCodeAddressMask(mask);
// If the highmem mask is the default-invalid,
// don't change it, keep everything consistently
// using the lowmem all-address-space mask.
if (process_sp->GetConcreteHighmemCodeAddressMask() !=
LLDB_INVALID_ADDRESS_MASK)
process_sp->SetHighmemCodeAddressMask(mask);
} else if (addr_range == eAddressMaskRangeHigh) {
process_sp->SetHighmemCodeAddressMask(mask);
} else {
Expand All @@ -1308,7 +1313,12 @@ void SBProcess::SetAddressMask(AddressMaskType type, addr_t mask,
case eAddressMaskTypeData:
if (addr_range == eAddressMaskRangeAll) {
process_sp->SetDataAddressMask(mask);
process_sp->SetHighmemDataAddressMask(mask);
// If the highmem mask is the default-invalid,
// don't change it, keep everything consistently
// using the lowmem all-address-space mask.
if (process_sp->GetConcreteHighmemDataAddressMask() !=
LLDB_INVALID_ADDRESS_MASK)
process_sp->SetHighmemDataAddressMask(mask);
} else if (addr_range == eAddressMaskRangeHigh) {
process_sp->SetHighmemDataAddressMask(mask);
} else {
Expand All @@ -1319,8 +1329,16 @@ void SBProcess::SetAddressMask(AddressMaskType type, addr_t mask,
if (addr_range == eAddressMaskRangeAll) {
process_sp->SetCodeAddressMask(mask);
process_sp->SetDataAddressMask(mask);
process_sp->SetHighmemCodeAddressMask(mask);
process_sp->SetHighmemDataAddressMask(mask);
// If the highmem masks are the default-invalid,
// don't change them, keep everything consistently
// using the lowmem all-address-space masks.
if (process_sp->GetConcreteHighmemDataAddressMask() !=
LLDB_INVALID_ADDRESS_MASK ||
process_sp->GetConcreteHighmemCodeAddressMask() !=
LLDB_INVALID_ADDRESS_MASK) {
process_sp->SetHighmemCodeAddressMask(mask);
process_sp->SetHighmemDataAddressMask(mask);
}
} else if (addr_range == eAddressMaskRangeHigh) {
process_sp->SetHighmemCodeAddressMask(mask);
process_sp->SetHighmemDataAddressMask(mask);
Expand Down
28 changes: 20 additions & 8 deletions lldb/source/Target/Process.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5681,21 +5681,21 @@ void Process::Flush() {
m_queue_list_stop_id = 0;
}

lldb::addr_t Process::GetCodeAddressMask() {
addr_t Process::GetCodeAddressMask() {
if (uint32_t num_bits_setting = GetVirtualAddressableBits())
return AddressableBits::AddressableBitToMask(num_bits_setting);

return m_code_address_mask;
}

lldb::addr_t Process::GetDataAddressMask() {
addr_t Process::GetDataAddressMask() {
if (uint32_t num_bits_setting = GetVirtualAddressableBits())
return AddressableBits::AddressableBitToMask(num_bits_setting);

return m_data_address_mask;
}

lldb::addr_t Process::GetHighmemCodeAddressMask() {
addr_t Process::GetHighmemCodeAddressMask() {
if (uint32_t num_bits_setting = GetHighmemVirtualAddressableBits())
return AddressableBits::AddressableBitToMask(num_bits_setting);

Expand All @@ -5704,7 +5704,7 @@ lldb::addr_t Process::GetHighmemCodeAddressMask() {
return GetCodeAddressMask();
}

lldb::addr_t Process::GetHighmemDataAddressMask() {
addr_t Process::GetHighmemDataAddressMask() {
if (uint32_t num_bits_setting = GetHighmemVirtualAddressableBits())
return AddressableBits::AddressableBitToMask(num_bits_setting);

Expand Down Expand Up @@ -6473,9 +6473,21 @@ void Process::SetAddressableBitMasks(AddressableBits bit_masks) {
}

if (high_memory_addr_bits != 0) {
addr_t high_addr_mask =
AddressableBits::AddressableBitToMask(high_memory_addr_bits);
SetHighmemCodeAddressMask(high_addr_mask);
SetHighmemDataAddressMask(high_addr_mask);
// If the same high and low mem address bits were specified,
// and we don't have a highmem setting for code and data currently,
// don't set the highmem masks.
// When we have separate high- and low- masks, the user
// setting `virtual-addressable-bits` only overrides the low
// memory masks, which most users would be surprised by.
// Leave the high memory masks unset, to make it clear that only the
// low memory masks are active.
if (high_memory_addr_bits != low_memory_addr_bits ||
m_highmem_code_address_mask != LLDB_INVALID_ADDRESS_MASK ||
m_highmem_data_address_mask != LLDB_INVALID_ADDRESS_MASK) {
addr_t high_addr_mask =
AddressableBits::AddressableBitToMask(high_memory_addr_bits);
SetHighmemCodeAddressMask(high_addr_mask);
SetHighmemDataAddressMask(high_addr_mask);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,17 @@ def reset_all_masks(self, process):
process.SetAddressMask(
lldb.eAddressMaskTypeAll,
lldb.LLDB_INVALID_ADDRESS_MASK,
lldb.eAddressMaskRangeAll,
lldb.eAddressMaskRangeLow,
)
process.SetAddressMask(
lldb.eAddressMaskTypeAll,
lldb.LLDB_INVALID_ADDRESS_MASK,
lldb.eAddressMaskRangeHigh,
)
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
@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(
Expand Down Expand Up @@ -80,7 +85,6 @@ def test_address_masks(self):
# 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(
Expand Down Expand Up @@ -113,7 +117,7 @@ def test_address_masks_target_supports_highmem_tests(self):
# 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
@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(
Expand All @@ -132,3 +136,26 @@ def test_address_masks_target_no_highmem(self):
self.runCmd("settings set target.process.highmem-virtual-addressable-bits 42")
self.assertEqual(0x0000000000007694, process.FixAddress(0x00265E950001F694))
self.assertEqual(0xFFFFFFFFFFFFF694, process.FixAddress(0xFFA65E950000F694))

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

process.SetAddressableBits(
lldb.eAddressMaskTypeAll, 64, lldb.eAddressMaskRangeLow
)
self.runCmd("settings set target.process.virtual-addressable-bits 47")
self.assertEqual(0xFFFFFE0044580BC4, process.FixAddress(0xFFE8FE0044580BC4))

self.reset_all_masks(process)
process.SetAddressableBits(
lldb.eAddressMaskTypeAll, 64, lldb.eAddressMaskRangeAll
)
self.runCmd("settings set target.process.virtual-addressable-bits 47")
self.assertEqual(0xFFFFFE0044580BC4, process.FixAddress(0xFFE8FE0044580BC4))
Loading