llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-lldb

Author: Jason Molenda (jasonmolenda)

<details>
<summary>Changes</summary>

[lldb] Add SBProcess methods for get/set/use address masks (#<!-- -->83095)

I'm reviving a patch from phabracator, https://reviews.llvm.org/D155905
which was approved but I wasn't thrilled with all the API I was adding
to SBProcess for all of the address mask types / memory regions. In this
update, I added enums to control type address mask type (code, data,
any) and address space specifiers (low, high, all) with defaulted
arguments for the most common case.

This patch is also fixing a bug in the "addressable bits to address
mask" calculation I added in AddressableBits::SetProcessMasks. If lldb
were told that 64 bits are valid for addressing, this method would
overflow the calculation and set an invalid mask. Added tests to check
this specific bug while I was adding these APIs.

This patch changes the value of "no mask set" from 0 to
LLDB_INVALID_ADDRESS_MASK, which is UINT64_MAX. A mask of all 1's
means "no bits are used for addressing" which is an impossible mask,
whereas a mask of 0 means "all bits are used for addressing" which
is possible.

I added a base class implementation of ABI::FixCodeAddress and
ABI::FixDataAddress that will apply the Process mask values if they
are set to a value other than LLDB_INVALID_ADDRESS_MASK.

I updated all the callers/users of the Mask methods which were
handling a value of 0 to mean invalid mask to use
LLDB_INVALID_ADDRESS_MASK.

I added code to the ABISysV_arm64 Fix override methods to apply the
Highmem masks if they have been set.  These will not be set on a
Linux environment, but I have tests in TestAddressMasks.py which
set the highmem masks and I need all Fix*Mask implementations to
check &amp; use them for the tests to pass.

rdar://123530562


---

Patch is 31.89 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/83663.diff


18 Files Affected:

- (modified) lldb/include/lldb/API/SBProcess.h (+114) 
- (modified) lldb/include/lldb/Target/ABI.h (+2-6) 
- (modified) lldb/include/lldb/Target/Process.h (+27-9) 
- (modified) lldb/include/lldb/Utility/AddressableBits.h (+3) 
- (modified) lldb/include/lldb/lldb-defines.h (+5) 
- (modified) lldb/include/lldb/lldb-enumerations.h (+16) 
- (modified) lldb/source/API/SBProcess.cpp (+92) 
- (modified) lldb/source/Commands/CommandObjectProcess.cpp (+1-1) 
- (modified) lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.cpp (+4-4) 
- (modified) lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.cpp (+30-10) 
- (modified) 
lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp 
(+2-1) 
- (modified) lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp (+2-2) 
- (modified) lldb/source/Target/ABI.cpp (+26) 
- (modified) lldb/source/Target/Process.cpp (+8-6) 
- (modified) lldb/source/Utility/AddressableBits.cpp (+10-2) 
- (added) lldb/test/API/python_api/process/address-masks/Makefile (+3) 
- (added) lldb/test/API/python_api/process/address-masks/TestAddressMasks.py 
(+74) 
- (added) lldb/test/API/python_api/process/address-masks/main.c (+5) 


``````````diff
diff --git a/lldb/include/lldb/API/SBProcess.h 
b/lldb/include/lldb/API/SBProcess.h
index 4f92a41f3028a2..7da3335a7234b7 100644
--- a/lldb/include/lldb/API/SBProcess.h
+++ b/lldb/include/lldb/API/SBProcess.h
@@ -407,6 +407,120 @@ class LLDB_API SBProcess {
   ///     the process isn't loaded from a core file.
   lldb::SBFileSpec GetCoreFile();
 
+  /// \{
+  /// \group Mask Address Methods
+  ///
+  /// \a type
+  /// All of the methods in this group take \a type argument
+  /// which is an AddressMaskType enum value.
+  /// There can be different address masks for code addresses and
+  /// data addresses, this argument can select which to get/set,
+  /// or to use when clearing non-addressable bits from an address.
+  /// This choice of mask can be important for example on AArch32
+  /// systems. Where instructions where instructions start on even addresses,
+  /// the 0th bit may be used to indicate that a function is thumb code.  On
+  /// such a target, the eAddressMaskTypeCode may clear the 0th bit from an
+  /// address to get the actual address Whereas eAddressMaskTypeData would not.
+  ///
+  /// \a addr_range
+  /// Many of the methods in this group take an \a addr_range argument
+  /// which is an AddressMaskRange enum value.
+  /// Needing to specify the address range is highly unusual, and the
+  /// default argument can be used in nearly all circumstances.
+  /// On some architectures (e.g., AArch64), it is possible to have
+  /// different page table setups for low and high memory, so different
+  /// numbers of bits relevant to addressing. It is possible to have
+  /// a program running in one half of memory and accessing the other
+  /// as heap, so we need to maintain two different sets of address masks
+  /// to debug this correctly.
+
+  /// Get the current address mask that will be applied to addresses
+  /// before reading from memory.
+  ///
+  /// \param[in] type
+  ///     See \ref Mask Address Methods description of this argument.
+  ///     eAddressMaskTypeAny is often a suitable value when code and
+  ///     data masks are the same on a given target.
+  ///
+  /// \param[in] addr_range
+  ///     See \ref Mask Address Methods description of this argument.
+  ///     This will default to eAddressMaskRangeLow which is the
+  ///     only set of masks used normally.
+  ///
+  /// \return
+  ///     The address mask currently in use.  Bits which are not used
+  ///     for addressing will be set to 1 in the mask.
+  lldb::addr_t GetAddressMask(
+      lldb::AddressMaskType type,
+      lldb::AddressMaskRange addr_range = lldb::eAddressMaskRangeLow);
+
+  /// Set the current address mask that can be applied to addresses
+  /// before reading from memory.
+  ///
+  /// \param[in] type
+  ///     See \ref Mask Address Methods description of this argument.
+  ///     eAddressMaskTypeAll is often a suitable value when the
+  ///     same mask is being set for both code and data.
+  ///
+  /// \param[in] mask
+  ///     The address mask to set.  Bits which are not used for addressing
+  ///     should be set to 1 in the mask.
+  ///
+  /// \param[in] addr_range
+  ///     See \ref Mask Address Methods description of this argument.
+  ///     This will default to eAddressMaskRangeLow which is the
+  ///     only set of masks used normally.
+  void SetAddressMask(
+      lldb::AddressMaskType type, lldb::addr_t mask,
+      lldb::AddressMaskRange addr_range = lldb::eAddressMaskRangeLow);
+
+  /// Set the number of bits used for addressing in this Process.
+  ///
+  /// On Darwin and similar systems, the addressable bits are expressed
+  /// as the number of low order bits that are relevant to addressing,
+  /// instead of a more general address mask.
+  /// This method calculates the correct mask value for a given number
+  /// of low order addressable bits.
+  ///
+  /// \param[in] type
+  ///     See \ref Mask Address Methods description of this argument.
+  ///     eAddressMaskTypeAll is often a suitable value when the
+  ///     same mask is being set for both code and data.
+  ///
+  /// \param[in] num_bits
+  ///     Number of bits that are used for addressing.
+  ///     For example, a value of 42 indicates that the low 42 bits
+  ///     are relevant for addressing, and that higher-order bits may
+  ///     be used for various metadata like pointer authentication,
+  ///     Type Byte Ignore, etc.
+  ///
+  /// \param[in] addr_range
+  ///     See \ref Mask Address Methods description of this argument.
+  ///     This will default to eAddressMaskRangeLow which is the
+  ///     only set of masks used normally.
+  void
+  SetAddressableBits(AddressMaskType type, uint32_t num_bits,
+                     AddressMaskRange addr_range = lldb::eAddressMaskRangeLow);
+
+  /// Clear the non-address bits of an \a addr value and return a
+  /// virtual address in memory.
+  ///
+  /// Bits that are not used in addressing may be used for other purposes;
+  /// pointer authentication, or metadata in the top byte, or the 0th bit
+  /// of armv7 code addresses to indicate arm/thumb are common examples.
+  ///
+  /// \param[in] addr
+  ///     The address that should be cleared of non-address bits.
+  ///
+  /// \param[in] type
+  ///     See \ref Mask Address Methods description of this argument.
+  ///     eAddressMaskTypeAny is the default value, correct when it
+  ///     is unknown if the address is a code or data address.
+  lldb::addr_t
+  FixAddress(lldb::addr_t addr,
+             lldb::AddressMaskType type = lldb::eAddressMaskTypeAny);
+  /// \}
+
   /// Allocate memory within the process.
   ///
   /// This function will allocate memory in the process's address space.
diff --git a/lldb/include/lldb/Target/ABI.h b/lldb/include/lldb/Target/ABI.h
index f600e29c7c4b0e..7b646d743346b7 100644
--- a/lldb/include/lldb/Target/ABI.h
+++ b/lldb/include/lldb/Target/ABI.h
@@ -122,8 +122,8 @@ class ABI : public PluginInterface {
   /// ARM uses bit zero to signify a code address is thumb, so any ARM ABI
   /// plug-ins would strip those bits.
   /// @{
-  virtual lldb::addr_t FixCodeAddress(lldb::addr_t pc) { return pc; }
-  virtual lldb::addr_t FixDataAddress(lldb::addr_t pc) { return pc; }
+  virtual lldb::addr_t FixCodeAddress(lldb::addr_t pc);
+  virtual lldb::addr_t FixDataAddress(lldb::addr_t pc);
   /// @}
 
   /// Use this method when you do not know, or do not care what kind of address
@@ -166,10 +166,6 @@ class ABI : public PluginInterface {
   lldb::ProcessWP m_process_wp;
   std::unique_ptr<llvm::MCRegisterInfo> m_mc_register_info_up;
 
-  virtual lldb::addr_t FixCodeAddress(lldb::addr_t pc, lldb::addr_t mask) {
-    return pc;
-  }
-
 private:
   ABI(const ABI &) = delete;
   const ABI &operator=(const ABI &) = delete;
diff --git a/lldb/include/lldb/Target/Process.h 
b/lldb/include/lldb/Target/Process.h
index 0ad626ffd3613c..e260e1b4b797bc 100644
--- a/lldb/include/lldb/Target/Process.h
+++ b/lldb/include/lldb/Target/Process.h
@@ -1422,9 +1422,23 @@ class Process : public 
std::enable_shared_from_this<Process>,
 
   virtual void DidExit() {}
 
+  /// Get the current address mask in the Process
+  ///
+  /// This mask can used to set/clear non-address bits in an addr_t.
+  ///
+  /// \return
+  ///   The current address mask.
+  ///   Bits which are set to 1 are not used for addressing.
+  ///   An address mask of 0 means all bits are used for addressing.
+  ///   An address mask of LLDB_INVALID_ADDRESS_MASK (all 1's) means
+  ///   that no mask has been set.
   lldb::addr_t GetCodeAddressMask();
   lldb::addr_t GetDataAddressMask();
 
+  /// The highmem masks are for targets where we may have different masks
+  /// for low memory versus high memory addresses, and they will be left
+  /// as LLDB_INVALID_ADDRESS_MASK normally, meaning the base masks
+  /// should be applied to all addresses.
   lldb::addr_t GetHighmemCodeAddressMask();
   lldb::addr_t GetHighmemDataAddressMask();
 
@@ -3096,16 +3110,20 @@ void PruneThreadPlans();
   // if run while destructing.  We use this flag to determine that.
   std::atomic<bool> m_destructing;
 
-  /// 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.
+  /// Mask for code an data addresses.
+  /// The default value LLDB_INVALID_ADDRESS_MASK means no mask has been set,
+  /// and addresses values should not be modified.
+  /// In these masks, the bits are set to 1 indicate bits that are not
+  /// significant for addressing.
+  /// The highmem masks are for targets where we may have different masks
+  /// for low memory versus high memory addresses, and they will be left
+  /// as LLDB_INVALID_ADDRESS_MASK normally, meaning the base masks
+  /// should be applied to all 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;
+  lldb::addr_t m_code_address_mask = LLDB_INVALID_ADDRESS_MASK;
+  lldb::addr_t m_data_address_mask = LLDB_INVALID_ADDRESS_MASK;
+  lldb::addr_t m_highmem_code_address_mask = LLDB_INVALID_ADDRESS_MASK;
+  lldb::addr_t m_highmem_data_address_mask = LLDB_INVALID_ADDRESS_MASK;
   /// @}
 
   bool m_clear_thread_plans_on_stop;
diff --git a/lldb/include/lldb/Utility/AddressableBits.h 
b/lldb/include/lldb/Utility/AddressableBits.h
index 13c21329a8c617..75752fcf840a44 100644
--- a/lldb/include/lldb/Utility/AddressableBits.h
+++ b/lldb/include/lldb/Utility/AddressableBits.h
@@ -10,6 +10,7 @@
 #define LLDB_UTILITY_ADDRESSABLEBITS_H
 
 #include "lldb/lldb-forward.h"
+#include "lldb/lldb-public.h"
 
 namespace lldb_private {
 
@@ -33,6 +34,8 @@ class AddressableBits {
 
   void SetHighmemAddressableBits(uint32_t highmem_addressing_bits);
 
+  static lldb::addr_t AddressableBitToMask(uint32_t addressable_bits);
+
   void SetProcessMasks(lldb_private::Process &process);
 
 private:
diff --git a/lldb/include/lldb/lldb-defines.h b/lldb/include/lldb/lldb-defines.h
index 469be92eabecf3..c7bd019c5c90eb 100644
--- a/lldb/include/lldb/lldb-defines.h
+++ b/lldb/include/lldb/lldb-defines.h
@@ -127,6 +127,11 @@
 #define MAX_PATH 260
 #endif
 
+/// Address Mask
+/// Bits not used for addressing are set to 1 in the mask;
+/// all mask bits set is an invalid value.
+#define LLDB_INVALID_ADDRESS_MASK UINT64_MAX
+
 // ignore GCC function attributes
 #if defined(_MSC_VER) && !defined(__clang__)
 #define __attribute__(X)
diff --git a/lldb/include/lldb/lldb-enumerations.h 
b/lldb/include/lldb/lldb-enumerations.h
index 85769071dae785..646f7bfda98475 100644
--- a/lldb/include/lldb/lldb-enumerations.h
+++ b/lldb/include/lldb/lldb-enumerations.h
@@ -1323,6 +1323,22 @@ enum SymbolDownload {
   eSymbolDownloadForeground = 2,
 };
 
+/// Used in the SBProcess AddressMask/FixAddress methods.
+enum AddressMaskType {
+  eAddressMaskTypeCode = 0,
+  eAddressMaskTypeData,
+  eAddressMaskTypeAny,
+  eAddressMaskTypeAll = eAddressMaskTypeAny
+};
+
+/// Used in the SBProcess AddressMask/FixAddress methods.
+enum AddressMaskRange {
+  eAddressMaskRangeLow = 0,
+  eAddressMaskRangeHigh,
+  eAddressMaskRangeAny,
+  eAddressMaskRangeAll = eAddressMaskRangeAny,
+};
+
 } // namespace lldb
 
 #endif // LLDB_LLDB_ENUMERATIONS_H
diff --git a/lldb/source/API/SBProcess.cpp b/lldb/source/API/SBProcess.cpp
index a9fe915324683e..b80664882ebcac 100644
--- a/lldb/source/API/SBProcess.cpp
+++ b/lldb/source/API/SBProcess.cpp
@@ -1255,6 +1255,98 @@ lldb::SBFileSpec SBProcess::GetCoreFile() {
   return SBFileSpec(core_file);
 }
 
+addr_t SBProcess::GetAddressMask(AddressMaskType type,
+                                 AddressMaskRange addr_range) {
+  LLDB_INSTRUMENT_VA(this, type, addr_range);
+
+  if (ProcessSP process_sp = GetSP()) {
+    switch (type) {
+    case eAddressMaskTypeCode:
+      if (addr_range == eAddressMaskRangeHigh)
+        return process_sp->GetHighmemCodeAddressMask();
+      else
+        return process_sp->GetCodeAddressMask();
+    case eAddressMaskTypeData:
+      if (addr_range == eAddressMaskRangeHigh)
+        return process_sp->GetHighmemDataAddressMask();
+      else
+        return process_sp->GetDataAddressMask();
+    case eAddressMaskTypeAny:
+      if (addr_range == eAddressMaskRangeHigh)
+        return process_sp->GetHighmemDataAddressMask();
+      else
+        return process_sp->GetDataAddressMask();
+    }
+  }
+  return LLDB_INVALID_ADDRESS_MASK;
+}
+
+void SBProcess::SetAddressMask(AddressMaskType type, addr_t mask,
+                               AddressMaskRange addr_range) {
+  LLDB_INSTRUMENT_VA(this, type, mask, addr_range);
+
+  if (ProcessSP process_sp = GetSP()) {
+    switch (type) {
+    case eAddressMaskTypeCode:
+      if (addr_range == eAddressMaskRangeAll) {
+        process_sp->SetCodeAddressMask(mask);
+        process_sp->SetHighmemCodeAddressMask(mask);
+      } else if (addr_range == eAddressMaskRangeHigh) {
+        process_sp->SetHighmemCodeAddressMask(mask);
+      } else {
+        process_sp->SetCodeAddressMask(mask);
+      }
+      break;
+    case eAddressMaskTypeData:
+      if (addr_range == eAddressMaskRangeAll) {
+        process_sp->SetDataAddressMask(mask);
+        process_sp->SetHighmemDataAddressMask(mask);
+      } else if (addr_range == eAddressMaskRangeHigh) {
+        process_sp->SetHighmemDataAddressMask(mask);
+      } else {
+        process_sp->SetDataAddressMask(mask);
+      }
+      break;
+    case eAddressMaskTypeAll:
+      if (addr_range == eAddressMaskRangeAll) {
+        process_sp->SetCodeAddressMask(mask);
+        process_sp->SetDataAddressMask(mask);
+        process_sp->SetHighmemCodeAddressMask(mask);
+        process_sp->SetHighmemDataAddressMask(mask);
+      } else if (addr_range == eAddressMaskRangeHigh) {
+        process_sp->SetHighmemCodeAddressMask(mask);
+        process_sp->SetHighmemDataAddressMask(mask);
+      } else {
+        process_sp->SetCodeAddressMask(mask);
+        process_sp->SetDataAddressMask(mask);
+      }
+      break;
+    }
+  }
+}
+
+void SBProcess::SetAddressableBits(AddressMaskType type, uint32_t num_bits,
+                                   AddressMaskRange addr_range) {
+  LLDB_INSTRUMENT_VA(this, type, num_bits, addr_range);
+
+  SetAddressMask(type, AddressableBits::AddressableBitToMask(num_bits),
+                 addr_range);
+}
+
+addr_t SBProcess::FixAddress(addr_t addr, AddressMaskType type) {
+  LLDB_INSTRUMENT_VA(this, addr, type);
+
+  if (ProcessSP process_sp = GetSP()) {
+    if (type == eAddressMaskTypeAny)
+      return process_sp->FixAnyAddress(addr);
+    else if (type == eAddressMaskTypeData)
+      return process_sp->FixDataAddress(addr);
+    else if (type == eAddressMaskTypeCode)
+      return process_sp->FixCodeAddress(addr);
+  }
+  return addr;
+}
+
 lldb::addr_t SBProcess::AllocateMemory(size_t size, uint32_t permissions,
                                        lldb::SBError &sb_error) {
   LLDB_INSTRUMENT_VA(this, size, permissions, sb_error);
diff --git a/lldb/source/Commands/CommandObjectProcess.cpp 
b/lldb/source/Commands/CommandObjectProcess.cpp
index 9ac97eb66b6232..3587a8f529e4ab 100644
--- a/lldb/source/Commands/CommandObjectProcess.cpp
+++ b/lldb/source/Commands/CommandObjectProcess.cpp
@@ -1408,7 +1408,7 @@ class CommandObjectProcessStatus : public 
CommandObjectParsed {
     if (m_options.m_verbose) {
       addr_t code_mask = process->GetCodeAddressMask();
       addr_t data_mask = process->GetDataAddressMask();
-      if (code_mask != 0) {
+      if (code_mask != LLDB_INVALID_ADDRESS_MASK) {
         int bits = std::bitset<64>(~code_mask).count();
         result.AppendMessageWithFormat(
             "Addressable code address mask: 0x%" PRIx64 "\n", code_mask);
diff --git a/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.cpp 
b/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.cpp
index f4ef9b4fc824b0..045d6a405e6972 100644
--- a/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.cpp
+++ b/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.cpp
@@ -814,11 +814,11 @@ addr_t ABIMacOSX_arm64::FixCodeAddress(addr_t pc) {
     mask = process_sp->GetCodeAddressMask();
     if (pc & pac_sign_extension) {
       addr_t highmem_mask = process_sp->GetHighmemCodeAddressMask();
-      if (highmem_mask)
+      if (highmem_mask != LLDB_INVALID_ADDRESS_MASK)
         mask = highmem_mask;
     }
   }
-  if (mask == 0)
+  if (mask == LLDB_INVALID_ADDRESS_MASK)
     mask = tbi_mask;
 
   return (pc & pac_sign_extension) ? pc | mask : pc & (~mask);
@@ -833,11 +833,11 @@ addr_t ABIMacOSX_arm64::FixDataAddress(addr_t pc) {
     mask = process_sp->GetDataAddressMask();
     if (pc & pac_sign_extension) {
       addr_t highmem_mask = process_sp->GetHighmemDataAddressMask();
-      if (highmem_mask)
+      if (highmem_mask != LLDB_INVALID_ADDRESS_MASK)
         mask = highmem_mask;
     }
   }
-  if (mask == 0)
+  if (mask == LLDB_INVALID_ADDRESS_MASK)
     mask = tbi_mask;
 
   return (pc & pac_sign_extension) ? pc | mask : pc & (~mask);
diff --git a/lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.cpp 
b/lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.cpp
index bf3c5ddd588977..cd7481f88efdd8 100644
--- a/lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.cpp
+++ b/lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.cpp
@@ -775,6 +775,8 @@ ValueObjectSP ABISysV_arm64::GetReturnValueObjectImpl(
 }
 
 lldb::addr_t ABISysV_arm64::FixAddress(addr_t pc, addr_t mask) {
+  if (mask == LLDB_INVALID_ADDRESS_MASK)
+    return pc;
   lldb::addr_t pac_sign_extension = 0x0080000000000000ULL;
   return (pc & pac_sign_extension) ? pc | mask : pc & (~mask);
 }
@@ -782,12 +784,12 @@ lldb::addr_t ABISysV_arm64::FixAddress(addr_t pc, addr_t 
mask) {
 // Reads code or data address mask for the current Linux process.
 static lldb::addr_t ReadLinuxProcessAddressMask(lldb::ProcessSP process_sp,
                                                 llvm::StringRef reg_name) {
-  // 0 means there isn't a mask or it has not been read yet.
-  // We do not return the top byte mask unless thread_sp is valid.
-  // This prevents calls to this function before the thread is setup locking
-  // in the value to just the top byte mask, in cases where pointer
-  // authentication might also be active.
-  uint64_t address_mask = 0;
+  // LLDB_INVALID_ADDRESS_MASK means there isn't a mask or it has not been read
+  // yet. We do not return the top byte mask unless thread_sp is valid. This
+  // prevents calls to this function before the thread is setup locking in the
+  // value to just the top byte mask, in cases where pointer authentication
+  // might also be active.
+  uint64_t address_mask = LLDB_INVALID_ADDRESS_MASK;
   lldb::ThreadSP thread_sp = process_sp->GetThreadList().GetSelectedThread();
   if (thread_sp) {
     // Linux configures user-space virtual addresses with top byte ignored.
@@ -814,11 +816,20 @@ static lldb::addr_t 
ReadLinuxProcessAddressMask(lldb::ProcessSP process_sp,
 lldb::addr_t ABISysV_arm64::FixCodeAddress(lldb::addr_t pc) {
   if (lldb::ProcessSP process_sp = GetProcessSP()) {
     if (process_sp->GetTarget().GetArchitecture().GetTriple().isOSLinux() &&
-        !process_sp->GetCodeAddressMask())
+        process_sp->GetCodeAddressMask() == LLDB_INVALID_ADDRESS_MASK)
       process_sp->SetCodeAddressMask(
           ReadLinuxProcessAddressMask(process_sp, "code_mask"));
 
-    return FixAddress(pc, process_sp->GetCodeAddressMask());
+    // b55 is the highest bit outside TBI (if it's enabled), use
+    // it to determine if the high bits are set to 0 or 1.
+    const addr_t pac_sign_extension = 0x0080000000000000ULL;
+    addr_t mask = process_sp->GetCodeAddressMask();
+    // Test if the high memory mask has been overriden separately
+    if (pc & pac_sign_extension &&
+        process_sp->GetHighmemCodeAddressMask() != LLDB_INVALID_ADDRESS_MASK)
+      mask = process_sp->GetHighmemCodeAddressMask();
+
+    return FixAddress(pc, mask);
   }
   return pc;
 }
@@ -826,11 +837,20 @@ lldb::addr_t ABISysV_arm64::FixCodeAddress(lldb::addr_t 
pc) {
 lldb::addr_t ABISysV_arm64::FixDataAddress(lldb::addr_t pc) {
   if (lldb::ProcessSP process_sp = GetProcessSP()) {
     if (process_sp->GetTarget().GetArchitecture().GetTriple().isOSLinux() &&
-        !process_sp->GetDataAddressMask())
+        pro...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/83663
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to