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/Symbol/ObjectFile.h b/lldb/include/lldb/Symbol/ObjectFile.h --- a/lldb/include/lldb/Symbol/ObjectFile.h +++ b/lldb/include/lldb/Symbol/ObjectFile.h @@ -498,15 +498,10 @@ /// object files can return an AddressableBits object that can can be /// used to set the address masks in the Process. /// - /// \param[out] address_bits - /// Can be used to set the Process address masks. - /// /// \return - /// Returns true if addressable bits metadata was found. - virtual bool GetAddressableBits(lldb_private::AddressableBits &address_bits) { - address_bits.Clear(); - return false; - } + /// Returns an AddressableBits object which can be used to set + /// the address masks in the Process. + virtual lldb_private::AddressableBits GetAddressableBits() { return {}; } /// When the ObjectFile is a core file, lldb needs to locate the "binary" in /// the core file. lldb can iterate over the pages looking for a valid 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,9 +29,11 @@ void SetAddressableBits(uint32_t lowmem_addressing_bits, uint32_t highmem_addressing_bits); - void SetProcessMasks(lldb_private::Process &process); + void SetLowmemAddressableBits(uint32_t lowmem_addressing_bits); + + void SetHighmemAddressableBits(uint32_t highmem_addressing_bits); - void Clear(); + void SetProcessMasks(lldb_private::Process &process); private: uint32_t m_low_memory_addr_bits; diff --git a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h --- a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h +++ b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h @@ -122,7 +122,7 @@ std::string GetIdentifierString() override; - bool GetAddressableBits(lldb_private::AddressableBits &address_bits) override; + lldb_private::AddressableBits GetAddressableBits() override; bool GetCorefileMainBinaryInfo(lldb::addr_t &value, bool &value_is_offset, lldb_private::UUID &uuid, diff --git a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp --- a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp +++ b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp @@ -5486,8 +5486,8 @@ return result; } -bool ObjectFileMachO::GetAddressableBits(AddressableBits &address_bits) { - address_bits.Clear(); +AddressableBits ObjectFileMachO::GetAddressableBits() { + AddressableBits addressable_bits; Log *log(GetLog(LLDBLog::Process)); ModuleSP module_sp(GetModule()); @@ -5515,24 +5515,24 @@ if (version == 3) { uint32_t num_addr_bits = m_data.GetU32_unchecked(&offset); if (num_addr_bits != 0) { - address_bits.SetAddressableBits(num_addr_bits); + addressable_bits.SetAddressableBits(num_addr_bits); } LLDB_LOGF(log, "LC_NOTE 'addrable bits' v3 found, value %d " "bits", num_addr_bits); - return true; + break; } if (version == 4) { uint32_t lo_addr_bits = m_data.GetU32_unchecked(&offset); uint32_t hi_addr_bits = m_data.GetU32_unchecked(&offset); - address_bits.SetAddressableBits(lo_addr_bits, hi_addr_bits); + addressable_bits.SetAddressableBits(lo_addr_bits, hi_addr_bits); LLDB_LOGF(log, "LC_NOTE 'addrable bits' v4 found, value %d & %d bits", lo_addr_bits, hi_addr_bits); - return true; + break; } } } @@ -5540,7 +5540,7 @@ offset = cmd_offset + lc.cmdsize; } } - return false; + return addressable_bits; } bool ObjectFileMachO::GetCorefileMainBinaryInfo(addr_t &value, diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h @@ -238,7 +238,7 @@ ArchSpec GetSystemArchitecture(); - bool GetAddressableBits(lldb_private::AddressableBits &addressable_bits); + lldb_private::AddressableBits GetAddressableBits(); bool GetHostname(std::string &s); diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp @@ -1415,17 +1415,17 @@ return m_host_arch; } -bool GDBRemoteCommunicationClient::GetAddressableBits( - lldb_private::AddressableBits &addressable_bits) { - addressable_bits.Clear(); +AddressableBits GDBRemoteCommunicationClient::GetAddressableBits() { + AddressableBits addressable_bits; if (m_qHostInfo_is_valid == eLazyBoolCalculate) GetHostInfo(); - if (m_low_mem_addressing_bits != 0 || m_high_mem_addressing_bits != 0) { - addressable_bits.SetAddressableBits(m_low_mem_addressing_bits, - m_high_mem_addressing_bits); - return true; - } - return false; + + // m_low_mem_addressing_bits and m_high_mem_addressing_bits + // will be 0 if we did not receive values; AddressableBits + // treats 0 as "unspecified". + addressable_bits.SetAddressableBits(m_low_mem_addressing_bits, + m_high_mem_addressing_bits); + return addressable_bits; } seconds GDBRemoteCommunicationClient::GetHostDefaultPacketTimeout() { 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 @@ -899,10 +899,8 @@ process_arch.GetTriple().getTriple()); } - AddressableBits addressable_bits; - if (m_gdb_comm.GetAddressableBits(addressable_bits)) { - addressable_bits.SetProcessMasks(*this); - } + AddressableBits addressable_bits = m_gdb_comm.GetAddressableBits(); + addressable_bits.SetProcessMasks(*this); if (process_arch.IsValid()) { const ArchSpec &target_arch = GetTarget().GetArchitecture(); @@ -2124,6 +2122,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 +2270,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 +2309,8 @@ } } + 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/Plugins/Process/mach-core/ProcessMachCore.cpp b/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp --- a/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp +++ b/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp @@ -574,10 +574,9 @@ CleanupMemoryRegionPermissions(); - AddressableBits addressable_bits; - if (core_objfile->GetAddressableBits(addressable_bits)) { - addressable_bits.SetProcessMasks(*this); - } + AddressableBits addressable_bits = core_objfile->GetAddressableBits(); + addressable_bits.SetProcessMasks(*this); + return error; } 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,28 +23,57 @@ 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) { - // In case either value is set to 0, indicating it was not set, use the - // other value. - if (m_low_memory_addr_bits == 0) - m_low_memory_addr_bits = m_high_memory_addr_bits; - if (m_high_memory_addr_bits == 0) - m_high_memory_addr_bits = m_low_memory_addr_bits; - - if (m_low_memory_addr_bits == 0) + if (m_low_memory_addr_bits == 0 && m_high_memory_addr_bits == 0) return; - addr_t address_mask = ~((1ULL << m_low_memory_addr_bits) - 1); - process.SetCodeAddressMask(address_mask); - process.SetDataAddressMask(address_mask); + // If we don't have an addressable bits value for low memory, + // see if we have a Code/Data mask already, and use that. + // Or use the high memory addressable bits value as a last + // resort. + addr_t low_addr_mask; + if (m_low_memory_addr_bits == 0) { + if (process.GetCodeAddressMask() != UINT64_MAX) + low_addr_mask = process.GetCodeAddressMask(); + else if (process.GetDataAddressMask() != UINT64_MAX) + low_addr_mask = process.GetDataAddressMask(); + else + low_addr_mask = ~((1ULL << m_high_memory_addr_bits) - 1); + } else { + low_addr_mask = ~((1ULL << m_low_memory_addr_bits) - 1); + } + + // If we don't have an addressable bits value for high memory, + // see if we have a Code/Data mask already, and use that. + // Or use the low memory addressable bits value as a last + // resort. + addr_t hi_addr_mask; + if (m_high_memory_addr_bits == 0) { + if (process.GetHighmemCodeAddressMask() != UINT64_MAX) + hi_addr_mask = process.GetHighmemCodeAddressMask(); + else if (process.GetHighmemDataAddressMask() != UINT64_MAX) + hi_addr_mask = process.GetHighmemDataAddressMask(); + else + hi_addr_mask = ~((1ULL << m_low_memory_addr_bits) - 1); + } else { + hi_addr_mask = ~((1ULL << m_high_memory_addr_bits) - 1); + } + + process.SetCodeAddressMask(low_addr_mask); + process.SetDataAddressMask(low_addr_mask); - if (m_low_memory_addr_bits != m_high_memory_addr_bits) { - lldb::addr_t hi_address_mask = ~((1ULL << m_high_memory_addr_bits) - 1); - process.SetHighmemCodeAddressMask(hi_address_mask); - process.SetHighmemDataAddressMask(hi_address_mask); + if (low_addr_mask != hi_addr_mask) { + process.SetHighmemCodeAddressMask(hi_addr_mask); + process.SetHighmemDataAddressMask(hi_addr_mask); } }