jasonmolenda updated this revision to Diff 527251.
jasonmolenda added a comment.
Updated patch with Alex and Jonas' feedback incorporated. Most significantly,
instead of making target.process.virtual-addressable-bits an array of uint
values (between zero to two of them), I am leaving virtual-addressable-bits
as-is, and adding a new target.process.highmem-virtual-addressable-bits
setting. When this is set, its value will be used for setting high-memory
signed addresses on AArch64 using the Apple ABI plugin. And the value in
virtual-addressable-bits will be used for clearing low-memory signed addresses
on AArch64 Apple. If this new highmem-virtual-addressable-bits is not set (the
99.9% most common case), virtual-addressable-bits applies to both address
ranges.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D151292/new/
https://reviews.llvm.org/D151292
Files:
lldb/include/lldb/Target/Process.h
lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.cpp
lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.h
lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
lldb/source/Target/Process.cpp
lldb/source/Target/TargetProperties.td
Index: lldb/source/Target/TargetProperties.td
===================================================================
--- lldb/source/Target/TargetProperties.td
+++ lldb/source/Target/TargetProperties.td
@@ -255,6 +255,9 @@
def VirtualAddressableBits: Property<"virtual-addressable-bits", "UInt64">,
DefaultUnsignedValue<0>,
Desc<"The number of bits used for addressing. If the value is 39, then bits 0..38 are used for addressing. The default value of 0 means unspecified.">;
+ def HighmemVirtualAddressableBits: Property<"highmem-virtual-addressable-bits", "UInt64">,
+ DefaultUnsignedValue<0>,
+ Desc<"The number of bits used for addressing high memory, when it differs from low memory in the same Process. When this is non-zero, target.process.virtual-addressable-bits will be the value for low memory (0x000... addresses) and this setting will be the value for high memory (0xfff... addresses). When this is zero, target.process.virtual-addressable-bits applies to all addresses. It is very uncommon to use this setting.">;
def FollowForkMode: Property<"follow-fork-mode", "Enum">,
DefaultEnumValue<"eFollowParent">,
EnumValues<"OptionEnumValues(g_follow_fork_mode_values)">,
Index: lldb/source/Target/Process.cpp
===================================================================
--- lldb/source/Target/Process.cpp
+++ lldb/source/Target/Process.cpp
@@ -227,6 +227,18 @@
const uint32_t idx = ePropertyVirtualAddressableBits;
SetPropertyAtIndex(idx, static_cast<uint64_t>(bits));
}
+
+uint32_t ProcessProperties::GetHighmemVirtualAddressableBits() const {
+ const uint32_t idx = ePropertyHighmemVirtualAddressableBits;
+ return GetPropertyAtIndexAs<uint64_t>(
+ idx, g_process_properties[idx].default_uint_value);
+}
+
+void ProcessProperties::SetHighmemVirtualAddressableBits(uint32_t bits) {
+ const uint32_t idx = ePropertyHighmemVirtualAddressableBits;
+ SetPropertyAtIndex(idx, static_cast<uint64_t>(bits));
+}
+
void ProcessProperties::SetPythonOSPluginPath(const FileSpec &file) {
const uint32_t idx = ePropertyPythonOSPluginPath;
SetPropertyAtIndex(idx, file);
@@ -5651,25 +5663,31 @@
}
lldb::addr_t Process::GetCodeAddressMask() {
- if (m_code_address_mask == 0) {
- if (uint32_t number_of_addressable_bits = GetVirtualAddressableBits()) {
- lldb::addr_t address_mask = ~((1ULL << number_of_addressable_bits) - 1);
- SetCodeAddressMask(address_mask);
- }
- }
+ if (uint32_t num_bits_setting = GetVirtualAddressableBits())
+ return ~((1ULL << num_bits_setting) - 1);
+
return m_code_address_mask;
}
lldb::addr_t Process::GetDataAddressMask() {
- if (m_data_address_mask == 0) {
- if (uint32_t number_of_addressable_bits = GetVirtualAddressableBits()) {
- lldb::addr_t address_mask = ~((1ULL << number_of_addressable_bits) - 1);
- SetDataAddressMask(address_mask);
- }
- }
+ if (uint32_t num_bits_setting = GetVirtualAddressableBits())
+ return ~((1ULL << num_bits_setting) - 1);
+
return m_data_address_mask;
}
+lldb::addr_t Process::GetHighmemCodeAddressMask() {
+ if (uint32_t num_bits_setting = GetHighmemVirtualAddressableBits())
+ return ~((1ULL << num_bits_setting) - 1);
+ return GetCodeAddressMask();
+}
+
+lldb::addr_t Process::GetHighmemDataAddressMask() {
+ if (uint32_t num_bits_setting = GetHighmemVirtualAddressableBits())
+ return ~((1ULL << num_bits_setting) - 1);
+ return GetDataAddressMask();
+}
+
void Process::DidExec() {
Log *log = GetLog(LLDBLog::Process);
LLDB_LOGF(log, "Process::%s()", __FUNCTION__);
Index: lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
===================================================================
--- lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
+++ lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
@@ -1080,15 +1080,18 @@
}
// If the kernel global with the T1Sz setting is available,
// update the target.process.virtual-addressable-bits to be correct.
+ // NB the xnu kernel always has T0Sz and T1Sz the same value. If
+ // it wasn't the same, we would need to set
+ // target.process.virtual-addressable-bits = T0Sz
+ // target.process.highmem-virtual-addressable-bits = T1Sz
symbol = m_kernel.GetModule()->FindFirstSymbolWithNameAndType(
arm64_T1Sz_value, eSymbolTypeData);
if (symbol) {
- const uint32_t orig_bits_value = m_process->GetVirtualAddressableBits();
- // Mark all bits as addressable so we don't strip any from our
- // memory read below, with an incorrect default value.
- // b55 is the sign extension bit with PAC, b56:63 are TBI,
- // don't mark those as addressable.
- m_process->SetVirtualAddressableBits(55);
+ const addr_t orig_code_mask = m_process->GetCodeAddressMask();
+ const addr_t orig_data_mask = m_process->GetDataAddressMask();
+
+ m_process->SetCodeAddressMask(0);
+ m_process->SetDataAddressMask(0);
Status error;
// gT1Sz is 8 bytes. We may run on a stripped kernel binary
// where we can't get the size accurately. Hardcode it.
@@ -1103,9 +1106,12 @@
// T1Sz is 25, then 64-25 == 39, bits 0..38 are used for
// addressing, bits 39..63 are used for PAC/TBI or whatever.
uint32_t virt_addr_bits = 64 - sym_value;
- m_process->SetVirtualAddressableBits(virt_addr_bits);
+ addr_t mask = ~((1ULL << virt_addr_bits) - 1);
+ m_process->SetCodeAddressMask(mask);
+ m_process->SetDataAddressMask(mask);
} else {
- m_process->SetVirtualAddressableBits(orig_bits_value);
+ m_process->SetCodeAddressMask(orig_code_mask);
+ m_process->SetDataAddressMask(orig_data_mask);
}
}
} else {
Index: lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.h
===================================================================
--- lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.h
+++ lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.h
@@ -62,7 +62,8 @@
return true;
}
- lldb::addr_t FixAddress(lldb::addr_t pc, lldb::addr_t mask) override;
+ lldb::addr_t FixCodeAddress(lldb::addr_t pc) override;
+ lldb::addr_t FixDataAddress(lldb::addr_t pc) override;
// Static Functions
Index: lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.cpp
===================================================================
--- lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.cpp
+++ lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.cpp
@@ -814,15 +814,41 @@
return return_valobj_sp;
}
-lldb::addr_t ABIMacOSX_arm64::FixAddress(addr_t pc, addr_t mask) {
- lldb::addr_t pac_sign_extension = 0x0080000000000000ULL;
- // When no mask is specified, clear/set the top byte; preserve
- // the low 55 bits (00..54) for addressing and bit 55 to indicate
- // sign.
- if (mask == 0) {
- // ~((1ULL<<55)-1)
- mask = 0xff80000000000000;
+addr_t ABIMacOSX_arm64::FixCodeAddress(addr_t pc) {
+ addr_t pac_sign_extension = 0x0080000000000000ULL;
+ addr_t tbi_mask = 0xff80000000000000ULL;
+ addr_t mask = 0;
+
+ if (ProcessSP process_sp = GetProcessSP()) {
+ mask = process_sp->GetCodeAddressMask();
+ if (pc & pac_sign_extension) {
+ addr_t highmem_mask = process_sp->GetHighmemCodeAddressMask();
+ if (highmem_mask)
+ mask = highmem_mask;
+ }
+ }
+ if (mask == 0)
+ mask = tbi_mask;
+
+ return (pc & pac_sign_extension) ? pc | mask : pc & (~mask);
+}
+
+addr_t ABIMacOSX_arm64::FixDataAddress(addr_t pc) {
+ addr_t pac_sign_extension = 0x0080000000000000ULL;
+ addr_t tbi_mask = 0xff80000000000000ULL;
+ addr_t mask = 0;
+
+ if (ProcessSP process_sp = GetProcessSP()) {
+ mask = process_sp->GetDataAddressMask();
+ if (pc & pac_sign_extension) {
+ addr_t highmem_mask = process_sp->GetHighmemDataAddressMask();
+ if (highmem_mask)
+ mask = highmem_mask;
+ }
}
+ if (mask == 0)
+ mask = tbi_mask;
+
return (pc & pac_sign_extension) ? pc | mask : pc & (~mask);
}
Index: lldb/include/lldb/Target/Process.h
===================================================================
--- lldb/include/lldb/Target/Process.h
+++ lldb/include/lldb/Target/Process.h
@@ -81,6 +81,8 @@
FileSpec GetPythonOSPluginPath() const;
uint32_t GetVirtualAddressableBits() const;
void SetVirtualAddressableBits(uint32_t bits);
+ uint32_t GetHighmemVirtualAddressableBits() const;
+ void SetHighmemVirtualAddressableBits(uint32_t bits);
void SetPythonOSPluginPath(const FileSpec &file);
bool GetIgnoreBreakpointsInExpressions() const;
void SetIgnoreBreakpointsInExpressions(bool ignore);
@@ -1371,6 +1373,9 @@
lldb::addr_t GetCodeAddressMask();
lldb::addr_t GetDataAddressMask();
+ lldb::addr_t GetHighmemCodeAddressMask();
+ lldb::addr_t GetHighmemDataAddressMask();
+
void SetCodeAddressMask(lldb::addr_t code_address_mask) {
m_code_address_mask = code_address_mask;
}
@@ -1379,6 +1384,14 @@
m_data_address_mask = data_address_mask;
}
+ void SetHighmemCodeAddressMask(lldb::addr_t code_address_mask) {
+ m_highmem_code_address_mask = code_address_mask;
+ }
+
+ void SetHighmemDataAddressMask(lldb::addr_t data_address_mask) {
+ m_highmem_data_address_mask = data_address_mask;
+ }
+
/// Get the Modification ID of the process.
///
/// \return
@@ -3000,9 +3013,13 @@
/// Mask for code an data addresses. The default value (0) means no mask is
/// set. The bits set to 1 indicate bits that are NOT significant for
/// addressing.
+ /// The highmem versions are for targets where we may have different masks
+ /// for low memory versus high memory addresses.
/// @{
lldb::addr_t m_code_address_mask = 0;
lldb::addr_t m_data_address_mask = 0;
+ lldb::addr_t m_highmem_code_address_mask = 0;
+ lldb::addr_t m_highmem_data_address_mask = 0;
/// @}
bool m_clear_thread_plans_on_stop;
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits