https://github.com/felipepiovezan created https://github.com/llvm/llvm-project/pull/159785
This is yet another variant of the Fix{Code,Data}Address methods, but tailored for pointers that both: 1. Are going to be used in-process, 2. Require authentication metadata. Currently, the callsite inside IRMemoryMap::WritePointerToMemory is an example of 1; the pointer written to memory will be used by JITed code during expression evaluation. An example of (2) can be found in the MTE extension on arm processors. An MTE-tagged pointer must preserve its normal bits in order for load instructions to complete without faulting. However, PAC bits must be stripped, as codegen for some expressions may generate regular load instructions for accesses to those (instead of the special PAC instructions). >From 6d601321cb9321477de3e073c4b213a414377303 Mon Sep 17 00:00:00 2001 From: Felipe de Azevedo Piovezan <fpiove...@apple.com> Date: Thu, 18 Sep 2025 14:45:00 -0700 Subject: [PATCH] [lldb] Introduce Process::FixAnyAddressPreservingAuthentication This is yet another variant of the Fix{Code,Data}Address methods, but tailored for pointers that both: 1. Are going to be used in-process, 2. Require authentication metadata. Currently, the callsite inside IRMemoryMap::WritePointerToMemory is an example of 1; the pointer written to memory will be used by JITed code during expression evaluation. An example of (2) can be found in the MTE extension on arm processors. An MTE-tagged pointer must preserve its normal bits in order for load instructions to complete without faulting. However, PAC bits must be stripped, as codegen for some expressions may generate regular load instructions for accesses to those (instead of the special PAC instructions). --- lldb/include/lldb/Target/ABI.h | 4 ++++ lldb/include/lldb/Target/Process.h | 5 +++++ lldb/source/Expression/IRMemoryMap.cpp | 2 +- lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.cpp | 9 +++++++++ lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.h | 1 + lldb/source/Target/Process.cpp | 6 ++++++ .../TestArmPointerMetadataStripping.py | 9 ++++++++- 7 files changed, 34 insertions(+), 2 deletions(-) diff --git a/lldb/include/lldb/Target/ABI.h b/lldb/include/lldb/Target/ABI.h index 1a1f1724222e3..0839df5ac7cf3 100644 --- a/lldb/include/lldb/Target/ABI.h +++ b/lldb/include/lldb/Target/ABI.h @@ -141,6 +141,10 @@ class ABI : public PluginInterface { return FixDataAddress(pc); } + virtual lldb::addr_t FixAnyAddressPreservingAuthentication(lldb::addr_t pc) { + return FixAnyAddress(pc); + } + llvm::MCRegisterInfo &GetMCRegisterInfo() { return *m_mc_register_info_up; } virtual void diff --git a/lldb/include/lldb/Target/Process.h b/lldb/include/lldb/Target/Process.h index dc75d98acea70..0ad891955cfd1 100644 --- a/lldb/include/lldb/Target/Process.h +++ b/lldb/include/lldb/Target/Process.h @@ -1464,6 +1464,11 @@ 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); + /// Strip pointer metadata except for the bits necessary to authenticate a + /// memory access. This is useful, for example, if `address` requires + /// authentication and it is going to be consumed in JITed code. + lldb::addr_t FixAnyAddressPreservingAuthentication(lldb::addr_t address); + /// Get the Modification ID of the process. /// /// \return diff --git a/lldb/source/Expression/IRMemoryMap.cpp b/lldb/source/Expression/IRMemoryMap.cpp index f978217fa8f2b..3df2fc072f227 100644 --- a/lldb/source/Expression/IRMemoryMap.cpp +++ b/lldb/source/Expression/IRMemoryMap.cpp @@ -647,7 +647,7 @@ void IRMemoryMap::WritePointerToMemory(lldb::addr_t process_address, if (it == m_allocations.end() || it->second.m_policy != AllocationPolicy::eAllocationPolicyHostOnly) if (auto process_sp = GetProcessWP().lock()) - pointer = process_sp->FixAnyAddress(pointer); + pointer = process_sp->FixAnyAddressPreservingAuthentication(pointer); Scalar scalar(pointer); diff --git a/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.cpp b/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.cpp index c595564f6fb8e..700413ed6d26a 100644 --- a/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.cpp +++ b/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.cpp @@ -792,6 +792,15 @@ addr_t ABIMacOSX_arm64::FixDataAddress(addr_t addr) { return DoFixAddr(addr, false /*is_code*/, GetProcessSP()); } +addr_t ABIMacOSX_arm64::FixAnyAddressPreservingAuthentication(addr_t addr) { + // Save the old MTE tag and restore it later. + constexpr addr_t mte_mask = 0x0f00000000000000ULL; + addr_t old_mte_tag = addr & mte_mask; + + addr_t fixed_addr = FixDataAddress(addr); + return old_mte_tag | (fixed_addr & (~mte_mask)); +} + void ABIMacOSX_arm64::Initialize() { PluginManager::RegisterPlugin(GetPluginNameStatic(), pluginDesc, CreateInstance); diff --git a/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.h b/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.h index c8851709f50ad..b7eb695bdc9c9 100644 --- a/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.h +++ b/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.h @@ -59,6 +59,7 @@ class ABIMacOSX_arm64 : public ABIAArch64 { lldb::addr_t FixCodeAddress(lldb::addr_t pc) override; lldb::addr_t FixDataAddress(lldb::addr_t pc) override; + lldb::addr_t FixAnyAddressPreservingAuthentication(lldb::addr_t pc) override; // Static Functions diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp index 3176852f0b724..562c8544af72b 100644 --- a/lldb/source/Target/Process.cpp +++ b/lldb/source/Target/Process.cpp @@ -5971,6 +5971,12 @@ addr_t Process::FixAnyAddress(addr_t addr) { return addr; } +addr_t Process::FixAnyAddressPreservingAuthentication(addr_t addr) { + if (ABISP abi_sp = GetABI()) + addr = abi_sp->FixAnyAddressPreservingAuthentication(addr); + return addr; +} + void Process::DidExec() { Log *log = GetLog(LLDBLog::Process); LLDB_LOGF(log, "Process::%s()", __FUNCTION__); diff --git a/lldb/test/API/macosx/arm-pointer-metadata-stripping/TestArmPointerMetadataStripping.py b/lldb/test/API/macosx/arm-pointer-metadata-stripping/TestArmPointerMetadataStripping.py index f61945b3eb4c9..4e63c3173bdd4 100644 --- a/lldb/test/API/macosx/arm-pointer-metadata-stripping/TestArmPointerMetadataStripping.py +++ b/lldb/test/API/macosx/arm-pointer-metadata-stripping/TestArmPointerMetadataStripping.py @@ -38,8 +38,15 @@ def test(self): symbols_file = self.create_symbols_file() self.runCmd(f"target module add {symbols_file}") + # The address of myglobal_json is: 0x1200AAAAAAAB1014 # The high order bits should be stripped. - self.expect_expr("get_high_bits(&myglobal_json)", result_value="0") + # On Darwin platforms, the lower nibble of the most significant byte is preserved. + if platform.system() == "Darwin": + expected_value = str(0x200000000000000) + else: + expected_value = "0" + + self.expect_expr("get_high_bits(&myglobal_json)", result_value=expected_value) # Mark all bits as used for addresses and ensure bits are no longer stripped. self.runCmd("settings set target.process.virtual-addressable-bits 64") _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits