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

Reply via email to