diff --git a/lldb/docs/lldb-gdb-remote.txt b/lldb/docs/lldb-gdb-remote.txt --- a/lldb/docs/lldb-gdb-remote.txt +++ b/lldb/docs/lldb-gdb-remote.txt @@ -1661,6 +1661,18 @@ // start code that may be changing the // page table setup, a dynamically set // value may be needed. +// "low_mem_addressing_bits" unsigned optional, specifies how many bits in +// addresses in low memory are significant +// for addressing, base 10. AArch64 can +// have different page table setups for low +// and high memory, and therefore a different +// number of bits used for addressing. +// "high_mem_addressing_bits" unsigned optional, specifies how many bits in +// addresses in high memory are significant +// for addressing, base 10. AArch64 can have +// different page table setups for low and +// high memory, and therefore a different +// number of bits used for addressing. // // BEST PRACTICES: // Since register values can be supplied with this packet, it is often useful diff --git a/lldb/include/lldb/Utility/AddressableBits.h b/lldb/include/lldb/Utility/AddressableBits.h --- a/lldb/include/lldb/Utility/AddressableBits.h +++ b/lldb/include/lldb/Utility/AddressableBits.h @@ -29,8 +29,14 @@ void SetAddressableBits(uint32_t lowmem_addressing_bits, uint32_t highmem_addressing_bits); + void SetLowmemAddressableBits(uint32_t lowmem_addressing_bits); + + void SetHighmemAddressableBits(uint32_t highmem_addressing_bits); + void SetProcessMasks(lldb_private::Process &process); + bool HasValue() const; + void Clear(); private: diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -2124,6 +2124,7 @@ QueueKind queue_kind = eQueueKindUnknown; uint64_t queue_serial_number = 0; ExpeditedRegisterMap expedited_register_map; + AddressableBits addressable_bits; while (stop_packet.GetNameColonValue(key, value)) { if (key.compare("metype") == 0) { // exception type in big endian hex @@ -2271,9 +2272,17 @@ } else if (key.compare("addressing_bits") == 0) { uint64_t addressing_bits; if (!value.getAsInteger(0, addressing_bits)) { - addr_t address_mask = ~((1ULL << addressing_bits) - 1); - SetCodeAddressMask(address_mask); - SetDataAddressMask(address_mask); + addressable_bits.SetAddressableBits(addressing_bits); + } + } else if (key.compare("low_mem_addressing_bits") == 0) { + uint64_t addressing_bits; + if (!value.getAsInteger(0, addressing_bits)) { + addressable_bits.SetLowmemAddressableBits(addressing_bits); + } + } else if (key.compare("high_mem_addressing_bits") == 0) { + uint64_t addressing_bits; + if (!value.getAsInteger(0, addressing_bits)) { + addressable_bits.SetHighmemAddressableBits(addressing_bits); } } else if (key.size() == 2 && ::isxdigit(key[0]) && ::isxdigit(key[1])) { uint32_t reg = UINT32_MAX; @@ -2302,6 +2311,10 @@ } } + if (addressable_bits.HasValue()) { + addressable_bits.SetProcessMasks(*this); + } + ThreadSP thread_sp = SetThreadStopInfo( tid, expedited_register_map, signo, thread_name, reason, description, exc_type, exc_data, thread_dispatch_qaddr, queue_vars_valid, diff --git a/lldb/source/Utility/AddressableBits.cpp b/lldb/source/Utility/AddressableBits.cpp --- a/lldb/source/Utility/AddressableBits.cpp +++ b/lldb/source/Utility/AddressableBits.cpp @@ -23,8 +23,14 @@ m_high_memory_addr_bits = highmem_addressing_bits; } -void AddressableBits::Clear() { - m_low_memory_addr_bits = m_high_memory_addr_bits = 0; +void AddressableBits::SetLowmemAddressableBits( + uint32_t lowmem_addressing_bits) { + m_low_memory_addr_bits = lowmem_addressing_bits; +} + +void AddressableBits::SetHighmemAddressableBits( + uint32_t highmem_addressing_bits) { + m_high_memory_addr_bits = highmem_addressing_bits; } void AddressableBits::SetProcessMasks(Process &process) { @@ -48,3 +54,11 @@ process.SetHighmemDataAddressMask(hi_address_mask); } } + +bool AddressableBits::HasValue() const { + return m_low_memory_addr_bits != 0 || m_high_memory_addr_bits != 0; +} + +void AddressableBits::Clear() { + m_low_memory_addr_bits = m_high_memory_addr_bits = 0; +}