[Lldb-commits] [lldb] 3ad618f - Update qHostInfo/LC_NOTE so multiple address bits can be specified
Jason Molenda via lldb-commits
lldb-commits at lists.llvm.org
Tue Aug 15 13:40:49 PDT 2023
Author: Jason Molenda
Date: 2023-08-15T13:21:33-07:00
New Revision: 3ad618f4aea1ef7442f7ff75d92632aec177a4fd
URL: https://github.com/llvm/llvm-project/commit/3ad618f4aea1ef7442f7ff75d92632aec177a4fd
DIFF: https://github.com/llvm/llvm-project/commit/3ad618f4aea1ef7442f7ff75d92632aec177a4fd.diff
LOG: Update qHostInfo/LC_NOTE so multiple address bits can be specified
On AArch64 systems, we may have different page table setups for
low memory and high memory, and therefore a different number of
bits used for addressing depending on which half of memory the
address is in.
This patch extends the qHostInfo and LC_NOTE "addrable bits" so
that it can specify the number of addressing bits in high memory
and in low memory separately. It builds on the patch I added in
https://reviews.llvm.org/D151292 where Process tracks the separate
address masks, and there is a user setting to set them manually.
Differential Revision: https://reviews.llvm.org/D157667
rdar://113225907
Added:
lldb/include/lldb/Utility/AddressableBits.h
lldb/source/Utility/AddressableBits.cpp
Modified:
lldb/docs/lldb-gdb-remote.txt
lldb/include/lldb/Symbol/ObjectFile.h
lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h
lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp
lldb/source/Utility/CMakeLists.txt
Removed:
################################################################################
diff --git a/lldb/docs/lldb-gdb-remote.txt b/lldb/docs/lldb-gdb-remote.txt
index 27adaa33d14045..bfc10133051a3a 100644
--- a/lldb/docs/lldb-gdb-remote.txt
+++ b/lldb/docs/lldb-gdb-remote.txt
@@ -978,6 +978,14 @@ addressing_bits: optional, specifies how many bits in addresses are
v8.3 ABIs that use pointer authentication, so lldb
knows which bits to clear/set to get the actual
addresses.
+low_mem_addressing_bits: optional, specifies how many bits in
+ addresses in low memory are significant for addressing, base 10.
+ AArch64 can have
diff erent page table setups for low and high
+ memory, and therefore a
diff erent number of bits used for addressing.
+high_mem_addressing_bits: optional, specifies how many bits in
+ addresses in high memory are significant for addressing, base 10.
+ AArch64 can have
diff erent page table setups for low and high
+ memory, and therefore a
diff erent number of bits used for addressing.
//----------------------------------------------------------------------
// "qGDBServerVersion"
diff --git a/lldb/include/lldb/Symbol/ObjectFile.h b/lldb/include/lldb/Symbol/ObjectFile.h
index 2fc1cc582d2ceb..02d1248e23c342 100644
--- a/lldb/include/lldb/Symbol/ObjectFile.h
+++ b/lldb/include/lldb/Symbol/ObjectFile.h
@@ -13,6 +13,7 @@
#include "lldb/Core/PluginInterface.h"
#include "lldb/Symbol/Symtab.h"
#include "lldb/Symbol/UnwindTable.h"
+#include "lldb/Utility/AddressableBits.h"
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/Endian.h"
#include "lldb/Utility/FileSpec.h"
@@ -494,13 +495,18 @@ class ObjectFile : public std::enable_shared_from_this<ObjectFile>,
/// Some object files may have the number of bits used for addressing
/// embedded in them, e.g. a Mach-O core file using an LC_NOTE. These
- /// object files can return the address mask that should be used in
- /// the Process.
+ /// 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
- /// The mask will have bits set which aren't used for addressing --
- /// typically, the high bits.
- /// Zero is returned when no address bits mask is available.
- virtual lldb::addr_t GetAddressMask() { return 0; }
+ /// Returns true if addressable bits metadata was found.
+ virtual bool GetAddressableBits(lldb_private::AddressableBits &address_bits) {
+ address_bits.Clear();
+ return false;
+ }
/// 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
new file mode 100644
index 00000000000000..d7e2e341569655
--- /dev/null
+++ b/lldb/include/lldb/Utility/AddressableBits.h
@@ -0,0 +1,43 @@
+//===-- AddressableBits.h ---------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_UTILITY_ADDRESSABLEBITS_H
+#define LLDB_UTILITY_ADDRESSABLEBITS_H
+
+#include "lldb/lldb-forward.h"
+
+namespace lldb_private {
+
+/// \class AddressableBits AddressableBits.h "lldb/Core/AddressableBits.h"
+/// A class which holds the metadata from a remote stub/corefile note
+/// about how many bits are used for addressing on this target.
+///
+class AddressableBits {
+public:
+ AddressableBits() : m_low_memory_addr_bits(0), m_high_memory_addr_bits(0) {}
+
+ /// When a single value is available for the number of bits.
+ void SetAddressableBits(uint32_t addressing_bits);
+
+ /// When we have separate values for low memory addresses and high memory
+ /// addresses.
+ void SetAddressableBits(uint32_t lowmem_addressing_bits,
+ uint32_t highmem_addressing_bits);
+
+ void SetProcessMasks(lldb_private::Process &process);
+
+ void Clear();
+
+private:
+ uint32_t m_low_memory_addr_bits;
+ uint32_t m_high_memory_addr_bits;
+};
+
+} // namespace lldb_private
+
+#endif // LLDB_UTILITY_ADDRESSABLEBITS_H
diff --git a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
index f407abb800aaa3..b737733c1b5148 100644
--- a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
+++ b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
@@ -5486,8 +5486,9 @@ std::string ObjectFileMachO::GetIdentifierString() {
return result;
}
-addr_t ObjectFileMachO::GetAddressMask() {
- addr_t mask = 0;
+bool ObjectFileMachO::GetAddressableBits(AddressableBits &address_bits) {
+ address_bits.Clear();
+
Log *log(GetLog(LLDBLog::Process));
ModuleSP module_sp(GetModule());
if (module_sp) {
@@ -5514,13 +5515,24 @@ addr_t ObjectFileMachO::GetAddressMask() {
if (version == 3) {
uint32_t num_addr_bits = m_data.GetU32_unchecked(&offset);
if (num_addr_bits != 0) {
- mask = ~((1ULL << num_addr_bits) - 1);
+ address_bits.SetAddressableBits(num_addr_bits);
}
LLDB_LOGF(log,
- "LC_NOTE 'addrable bits' found, value %d bits, "
- "mask 0x%" PRIx64,
- num_addr_bits, mask);
- break;
+ "LC_NOTE 'addrable bits' v3 found, value %d "
+ "bits",
+ num_addr_bits);
+ return true;
+ }
+ 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);
+ LLDB_LOGF(log,
+ "LC_NOTE 'addrable bits' v4 found, value %d & %d bits",
+ lo_addr_bits, hi_addr_bits);
+
+ return true;
}
}
}
@@ -5528,7 +5540,7 @@ addr_t ObjectFileMachO::GetAddressMask() {
offset = cmd_offset + lc.cmdsize;
}
}
- return mask;
+ return false;
}
bool ObjectFileMachO::GetCorefileMainBinaryInfo(addr_t &value,
@@ -6669,10 +6681,12 @@ bool ObjectFileMachO::SaveCore(const lldb::ProcessSP &process_sp,
addrable_bits_lcnote_up->name = "addrable bits";
addrable_bits_lcnote_up->payload_file_offset = file_offset;
int bits = std::bitset<64>(~address_mask).count();
- addrable_bits_lcnote_up->payload.PutHex32(3); // version
+ addrable_bits_lcnote_up->payload.PutHex32(4); // version
+ addrable_bits_lcnote_up->payload.PutHex32(
+ bits); // # of bits used for low addresses
addrable_bits_lcnote_up->payload.PutHex32(
- bits); // # of bits used for addressing
- addrable_bits_lcnote_up->payload.PutHex64(0); // unused
+ bits); // # of bits used for high addresses
+ addrable_bits_lcnote_up->payload.PutHex32(0); // reserved
file_offset += addrable_bits_lcnote_up->payload.GetSize();
diff --git a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h
index 7099a4fbadf405..3f6acbf4832b7e 100644
--- a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h
+++ b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h
@@ -122,7 +122,7 @@ class ObjectFileMachO : public lldb_private::ObjectFile {
std::string GetIdentifierString() override;
- lldb::addr_t GetAddressMask() override;
+ bool GetAddressableBits(lldb_private::AddressableBits &address_bits) override;
bool GetCorefileMainBinaryInfo(lldb::addr_t &value, bool &value_is_offset,
lldb_private::UUID &uuid,
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
index c6503129685ab4..f836f08c4c847a 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
@@ -1265,7 +1265,15 @@ bool GDBRemoteCommunicationClient::GetHostInfo(bool force) {
if (!value.getAsInteger(0, pointer_byte_size))
++num_keys_decoded;
} else if (name.equals("addressing_bits")) {
- if (!value.getAsInteger(0, m_addressing_bits))
+ if (!value.getAsInteger(0, m_low_mem_addressing_bits)) {
+ m_high_mem_addressing_bits = m_low_mem_addressing_bits;
+ ++num_keys_decoded;
+ }
+ } else if (name.equals("high_mem_addressing_bits")) {
+ if (!value.getAsInteger(0, m_high_mem_addressing_bits))
+ ++num_keys_decoded;
+ } else if (name.equals("low_mem_addressing_bits")) {
+ if (!value.getAsInteger(0, m_low_mem_addressing_bits))
++num_keys_decoded;
} else if (name.equals("os_version") ||
name.equals("version")) // Older debugserver binaries used
@@ -1407,11 +1415,19 @@ GDBRemoteCommunicationClient::GetHostArchitecture() {
return m_host_arch;
}
-uint32_t GDBRemoteCommunicationClient::GetAddressingBits() {
+bool GDBRemoteCommunicationClient::GetAddressableBits(
+ lldb_private::AddressableBits &addressable_bits) {
+ addressable_bits.Clear();
if (m_qHostInfo_is_valid == eLazyBoolCalculate)
GetHostInfo();
- return m_addressing_bits;
+ 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;
}
+
seconds GDBRemoteCommunicationClient::GetHostDefaultPacketTimeout() {
if (m_qHostInfo_is_valid == eLazyBoolCalculate)
GetHostInfo();
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
index 6cf5de68911be2..fcdf7541ae25f2 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
@@ -19,6 +19,7 @@
#include <vector>
#include "lldb/Host/File.h"
+#include "lldb/Utility/AddressableBits.h"
#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/GDBRemote.h"
#include "lldb/Utility/ProcessInfo.h"
@@ -237,7 +238,7 @@ class GDBRemoteCommunicationClient : public GDBRemoteClientBase {
ArchSpec GetSystemArchitecture();
- uint32_t GetAddressingBits();
+ bool GetAddressableBits(lldb_private::AddressableBits &addressable_bits);
bool GetHostname(std::string &s);
@@ -580,7 +581,8 @@ class GDBRemoteCommunicationClient : public GDBRemoteClientBase {
lldb::tid_t m_curr_tid_run = LLDB_INVALID_THREAD_ID;
uint32_t m_num_supported_hardware_watchpoints = 0;
- uint32_t m_addressing_bits = 0;
+ uint32_t m_low_mem_addressing_bits = 0;
+ uint32_t m_high_mem_addressing_bits = 0;
ArchSpec m_host_arch;
std::string m_host_distribution_id;
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index 336f0607e6d57d..2c35957d2e55ae 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -899,10 +899,9 @@ void ProcessGDBRemote::DidLaunchOrAttach(ArchSpec &process_arch) {
process_arch.GetTriple().getTriple());
}
- if (int addressable_bits = m_gdb_comm.GetAddressingBits()) {
- lldb::addr_t address_mask = ~((1ULL << addressable_bits) - 1);
- SetCodeAddressMask(address_mask);
- SetDataAddressMask(address_mask);
+ AddressableBits addressable_bits;
+ if (m_gdb_comm.GetAddressableBits(addressable_bits)) {
+ addressable_bits.SetProcessMasks(*this);
}
if (process_arch.IsValid()) {
diff --git a/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp b/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp
index c93a2a2479aa6b..9ad6d70e25299d 100644
--- a/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp
+++ b/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp
@@ -509,10 +509,9 @@ Status ProcessMachCore::DoLoadCore() {
CleanupMemoryRegionPermissions();
- addr_t address_mask = core_objfile->GetAddressMask();
- if (address_mask != 0) {
- SetCodeAddressMask(address_mask);
- SetDataAddressMask(address_mask);
+ AddressableBits addressable_bits;
+ if (core_objfile->GetAddressableBits(addressable_bits)) {
+ addressable_bits.SetProcessMasks(*this);
}
return error;
}
diff --git a/lldb/source/Utility/AddressableBits.cpp b/lldb/source/Utility/AddressableBits.cpp
new file mode 100644
index 00000000000000..29033ea67ec37e
--- /dev/null
+++ b/lldb/source/Utility/AddressableBits.cpp
@@ -0,0 +1,50 @@
+//===-- AddressableBits.cpp -----------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Utility/AddressableBits.h"
+#include "lldb/Target/Process.h"
+#include "lldb/lldb-types.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+void AddressableBits::SetAddressableBits(uint32_t addressing_bits) {
+ m_low_memory_addr_bits = m_high_memory_addr_bits = addressing_bits;
+}
+
+void AddressableBits::SetAddressableBits(uint32_t lowmem_addressing_bits,
+ uint32_t highmem_addressing_bits) {
+ m_low_memory_addr_bits = lowmem_addressing_bits;
+ m_high_memory_addr_bits = highmem_addressing_bits;
+}
+
+void AddressableBits::Clear() {
+ m_low_memory_addr_bits = m_high_memory_addr_bits = 0;
+}
+
+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)
+ return;
+
+ addr_t address_mask = ~((1ULL << m_low_memory_addr_bits) - 1);
+ process.SetCodeAddressMask(address_mask);
+ process.SetDataAddressMask(address_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);
+ }
+}
diff --git a/lldb/source/Utility/CMakeLists.txt b/lldb/source/Utility/CMakeLists.txt
index b376ace0ebe3d0..16afab1113a970 100644
--- a/lldb/source/Utility/CMakeLists.txt
+++ b/lldb/source/Utility/CMakeLists.txt
@@ -24,6 +24,7 @@ if (NOT HAVE_CXX_ATOMICS64_WITHOUT_LIB )
endif()
add_lldb_library(lldbUtility NO_INTERNAL_DEPENDENCIES
+ AddressableBits.cpp
ArchSpec.cpp
Args.cpp
Baton.cpp
More information about the lldb-commits
mailing list