[Lldb-commits] [lldb] [lldb] Add SBProcess methods for get/set/use address masks (PR #83095)

Jason Molenda via lldb-commits lldb-commits at lists.llvm.org
Thu Feb 29 14:05:03 PST 2024


https://github.com/jasonmolenda updated https://github.com/llvm/llvm-project/pull/83095

>From dae16776e8c97158e8965e4d0e950cd2ce836f75 Mon Sep 17 00:00:00 2001
From: Jason Molenda <jason at molenda.com>
Date: Mon, 26 Feb 2024 18:05:27 -0800
Subject: [PATCH 1/4] [lldb] Add SBProcess methods for get/set/use address
 masks

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.

rdar://123530562
---
 lldb/include/lldb/API/SBProcess.h             | 123 ++++++++++++++++++
 lldb/include/lldb/Utility/AddressableBits.h   |   3 +
 lldb/include/lldb/lldb-enumerations.h         |  14 ++
 lldb/source/API/SBProcess.cpp                 |  89 +++++++++++++
 lldb/source/Utility/AddressableBits.cpp       |  12 +-
 .../python_api/process/address-masks/Makefile |   3 +
 .../process/address-masks/TestAddressMasks.py |  64 +++++++++
 .../python_api/process/address-masks/main.c   |   5 +
 8 files changed, 311 insertions(+), 2 deletions(-)
 create mode 100644 lldb/test/API/python_api/process/address-masks/Makefile
 create mode 100644 lldb/test/API/python_api/process/address-masks/TestAddressMasks.py
 create mode 100644 lldb/test/API/python_api/process/address-masks/main.c

diff --git a/lldb/include/lldb/API/SBProcess.h b/lldb/include/lldb/API/SBProcess.h
index 4f92a41f3028a2..7e9ad7d9a274f2 100644
--- a/lldb/include/lldb/API/SBProcess.h
+++ b/lldb/include/lldb/API/SBProcess.h
@@ -407,6 +407,129 @@ class LLDB_API SBProcess {
   ///     the process isn't loaded from a core file.
   lldb::SBFileSpec GetCoreFile();
 
+  /// Get the current address mask that can be applied to addresses
+  /// before reading from memory.
+  ///
+  /// \param[in] type
+  ///     lldb may have different address masks for code and data
+  ///     addresses.  Either can be requested, or most commonly,
+  ///     eAddressMaskTypeAny can be requested and the least specific
+  ///     mask will be fetched.  e.g. on a target where instructions
+  ///     are word aligned, the Code mask might clear the low 2 bits.
+  ///
+  /// \param[in] addr_range
+  ///     Specify whether the address mask for high or low address spaces
+  ///     is requested.
+  ///     It is highly unusual to have different address masks in high
+  ///     or low memory, and by default the eAddressMaskRangeLow is the
+  ///     only one used for both types of addresses, the default value for
+  ///     this argument is the correct one.
+  ///
+  ///     On some architectures like AArch64, it is possible to have
+  ///     different page table setups for low and high memory, so different
+  ///     numbers of bits relevant to addressing, and it is possible to have
+  ///     a program running in one half of memory and accessing the other
+  ///     as heap, etc.  In that case the eAddressMaskRangeLow and
+  ///     eAddressMaskRangeHigh will have different masks that must be handled.
+  ///
+  /// \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
+  ///     lldb may have different address masks for code and data
+  ///     addresses.  Either can be set, or most commonly,
+  ///     eAddressMaskTypeAll can be set for both types of addresses.
+  ///     An example where they could be different is a target where
+  ///     instructions are word aligned, so the low 2 bits are always
+  ///     zero.
+  ///
+  /// \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
+  ///     Specify whether the address mask for high or low address spaces
+  ///     is being set.
+  ///     It is highly unusual to have different address masks in high
+  ///     or low memory, and by default the eAddressMaskRangeLow is the
+  ///     only one used for both types of addresses, the default value for
+  ///     this argument is the correct one.
+  ///
+  ///     On some architectures like AArch64, it is possible to have
+  ///     different page table setups for low and high memory, so different
+  ///     numbers of bits relevant to addressing, and it is possible to have
+  ///     a program running in one half of memory and accessing the other
+  ///     as heap, etc.  In that case the eAddressMaskRangeLow and
+  ///     eAddressMaskRangeHigh will have different masks that must be
+  ///     specified.
+  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.
+  ///
+  /// In some environments, the number of bits that are used for addressing
+  /// is the natural representation insted of a mask; this method calculates
+  /// the addressing mask that lldb uses internally from that number.
+  ///
+  /// \param[in] type
+  ///     lldb may have different address masks for code and data
+  ///     addresses.  Either can be set, or most commonly,
+  ///     eAddressMaskTypeAll can be set for both types of addresses.
+  ///     An example where they could be different is a target where
+  ///     instructions are word aligned, so the low 2 bits are always
+  ///     zero.
+  ///
+  /// \param[in] num_bits
+  ///     Number of bits that are used for addressing.  e.g. the low 42
+  ///     bits may be the only ones used for addressing, and high bits may
+  ///     store metadata and should be ignored by lldb.
+  ///
+  /// \param[in] addr_range
+  ///     Specify whether the address mask for high or low address spaces
+  ///     is being set.
+  ///     It is highly unusual to have different address masks in high
+  ///     or low memory, and by default the eAddressMaskRangeLow is the
+  ///     only one used for both types of addresses, the default value for
+  ///     this argument is the correct one.
+  ///
+  ///     On some architectures like AArch64, it is possible to have
+  ///     different page table setups for low and high memory, so different
+  ///     numbers of bits relevant to addressing, and it is possible to have
+  ///     a program running in one half of memory and accessing the other
+  ///     as heap, etc.  In that case the eAddressMaskRangeLow and
+  ///     eAddressMaskRangeHigh will have different masks that must be
+  ///     specified.
+  void
+  SetAddressableBits(AddressMaskType type, uint32_t num_bits,
+                     AddressMaskRange addr_range = lldb::eAddressMaskRangeLow);
+
+  /// Clear the non-addressable 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-addressable bits.
+  ///
+  /// \param[in] type
+  ///     If the address is known to be a code address (address of a function,
+  ///     for example), eAddressMaskTypeCode may be passed, which may have
+  ///     stricter address clearing than data addresses e.g. the low 2 bits
+  ///     being unused for code addresses on AArch64.
+  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/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-enumerations.h b/lldb/include/lldb/lldb-enumerations.h
index 85769071dae785..853370bf5eb515 100644
--- a/lldb/include/lldb/lldb-enumerations.h
+++ b/lldb/include/lldb/lldb-enumerations.h
@@ -1323,6 +1323,20 @@ enum SymbolDownload {
   eSymbolDownloadForeground = 2,
 };
 
+enum AddressMaskType {
+  eAddressMaskTypeCode = 0,
+  eAddressMaskTypeData,
+  eAddressMaskTypeAny,
+  eAddressMaskTypeAll = eAddressMaskTypeAny
+};
+
+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..7edaa6b84fd7d7 100644
--- a/lldb/source/API/SBProcess.cpp
+++ b/lldb/source/API/SBProcess.cpp
@@ -1255,6 +1255,95 @@ lldb::SBFileSpec SBProcess::GetCoreFile() {
   return SBFileSpec(core_file);
 }
 
+addr_t SBProcess::GetAddressMask(AddressMaskType type,
+                                 AddressMaskRange addr_range) {
+  LLDB_INSTRUMENT_VA(this, type, addr_range);
+  addr_t default_mask = 0;
+  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 default_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/Utility/AddressableBits.cpp b/lldb/source/Utility/AddressableBits.cpp
index c6e25f608da73d..7f9d7ec6c1349c 100644
--- a/lldb/source/Utility/AddressableBits.cpp
+++ b/lldb/source/Utility/AddressableBits.cpp
@@ -33,18 +33,26 @@ void AddressableBits::SetHighmemAddressableBits(
   m_high_memory_addr_bits = highmem_addressing_bits;
 }
 
+addr_t AddressableBits::AddressableBitToMask(uint32_t addressable_bits) {
+  assert(addressable_bits <= sizeof(addr_t) * 8);
+  if (addressable_bits == 64)
+    return 0; // all bits used for addressing
+  else
+    return ~((1ULL << addressable_bits) - 1);
+}
+
 void AddressableBits::SetProcessMasks(Process &process) {
   if (m_low_memory_addr_bits == 0 && m_high_memory_addr_bits == 0)
     return;
 
   if (m_low_memory_addr_bits != 0) {
-    addr_t low_addr_mask = ~((1ULL << m_low_memory_addr_bits) - 1);
+    addr_t low_addr_mask = AddressableBitToMask(m_low_memory_addr_bits);
     process.SetCodeAddressMask(low_addr_mask);
     process.SetDataAddressMask(low_addr_mask);
   }
 
   if (m_high_memory_addr_bits != 0) {
-    addr_t hi_addr_mask = ~((1ULL << m_high_memory_addr_bits) - 1);
+    addr_t hi_addr_mask = AddressableBitToMask(m_high_memory_addr_bits);
     process.SetHighmemCodeAddressMask(hi_addr_mask);
     process.SetHighmemDataAddressMask(hi_addr_mask);
   }
diff --git a/lldb/test/API/python_api/process/address-masks/Makefile b/lldb/test/API/python_api/process/address-masks/Makefile
new file mode 100644
index 00000000000000..10495940055b63
--- /dev/null
+++ b/lldb/test/API/python_api/process/address-masks/Makefile
@@ -0,0 +1,3 @@
+C_SOURCES := main.c
+
+include Makefile.rules
diff --git a/lldb/test/API/python_api/process/address-masks/TestAddressMasks.py b/lldb/test/API/python_api/process/address-masks/TestAddressMasks.py
new file mode 100644
index 00000000000000..4a6a737e94f9d9
--- /dev/null
+++ b/lldb/test/API/python_api/process/address-masks/TestAddressMasks.py
@@ -0,0 +1,64 @@
+"""Test Python APIs for setting, getting, and using address masks."""
+
+import os
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+
+class AddressMasksTestCase(TestBase):
+    NO_DEBUG_INFO_TESTCASE = True
+
+    def test_address_masks(self):
+        self.build()
+        (target, process, t, bp) = lldbutil.run_to_source_breakpoint(
+            self, "break here", lldb.SBFileSpec("main.c")
+        )
+
+        process.SetAddressableBits(lldb.eAddressMaskTypeAll, 42)
+        self.assertEqual(0x0000029500003F94, process.FixAddress(0x00265E9500003F94))
+
+        # ~((1ULL<<42)-1) == 0xfffffc0000000000
+        process.SetAddressMask(lldb.eAddressMaskTypeAll, 0xFFFFFC0000000000)
+        self.assertEqual(0x0000029500003F94, process.FixAddress(0x00265E9500003F94))
+
+        # Check that all bits can pass through unmodified
+        process.SetAddressableBits(lldb.eAddressMaskTypeAll, 64)
+        self.assertEqual(0x00265E9500003F94, process.FixAddress(0x00265E9500003F94))
+
+        process.SetAddressableBits(
+            lldb.eAddressMaskTypeAll, 42, lldb.eAddressMaskRangeLow
+        )
+        process.SetAddressableBits(
+            lldb.eAddressMaskTypeAll, 15, lldb.eAddressMaskRangeHigh
+        )
+        self.assertEqual(0x000002950001F694, process.FixAddress(0x00265E950001F694))
+        self.assertEqual(0xFFFFFFFFFFFFF694, process.FixAddress(0xFFA65E950000F694))
+
+        process.SetAddressableBits(
+            lldb.eAddressMaskTypeAll, 42, lldb.eAddressMaskRangeAll
+        )
+        self.assertEqual(0x000002950001F694, process.FixAddress(0x00265E950001F694))
+        self.assertEqual(0xFFFFFE950000F694, process.FixAddress(0xFFA65E950000F694))
+
+        process.SetAddressMask(lldb.eAddressMaskTypeCode, 0xFFFFFC0000000003)
+        self.assertEqual(0x000002950001F697, process.FixAddress(0x00265E950001F697))
+        self.assertEqual(0xFFFFFE950000F697, process.FixAddress(0xFFA65E950000F697))
+        self.assertEqual(
+            0x000002950001F697,
+            process.FixAddress(0x00265E950001F697, lldb.eAddressMaskTypeData),
+        )
+        self.assertEqual(
+            0x000002950001F694,
+            process.FixAddress(0x00265E950001F697, lldb.eAddressMaskTypeCode),
+        )
+
+        # The user can override whatever settings the Process thinks should be used.
+        process.SetAddressableBits(
+            lldb.eAddressMaskTypeAll, 42, lldb.eAddressMaskRangeAll
+        )
+        self.runCmd("settings set target.process.virtual-addressable-bits 15")
+        self.runCmd("settings set target.process.highmem-virtual-addressable-bits 15")
+        self.assertEqual(0x0000000000007694, process.FixAddress(0x00265E950001F694))
+        self.assertEqual(0xFFFFFFFFFFFFF694, process.FixAddress(0xFFA65E950000F694))
diff --git a/lldb/test/API/python_api/process/address-masks/main.c b/lldb/test/API/python_api/process/address-masks/main.c
new file mode 100644
index 00000000000000..f21a10a16d5a75
--- /dev/null
+++ b/lldb/test/API/python_api/process/address-masks/main.c
@@ -0,0 +1,5 @@
+#include <stdio.h>
+
+int main(int argc, char const *argv[]) {
+  puts("Hello address masking world"); // break here
+}

>From 20653227a94330648e7f1016fc5f278e4e2eb27f Mon Sep 17 00:00:00 2001
From: Jason Molenda <jmolenda at apple.com>
Date: Tue, 27 Feb 2024 15:36:53 -0800
Subject: [PATCH 2/4] Doxygen group these methods in SBProcess.h, add longer
 form definitions for the `type` and `addr_range` arguments that are used by
 all of them, and refer back to those longer descriptions in each individual
 message.

Fix the descriptions as suggested by David and Will.
---
 lldb/include/lldb/API/SBProcess.h     | 124 ++++++++++++--------------
 lldb/include/lldb/lldb-enumerations.h |   2 +
 2 files changed, 58 insertions(+), 68 deletions(-)

diff --git a/lldb/include/lldb/API/SBProcess.h b/lldb/include/lldb/API/SBProcess.h
index 7e9ad7d9a274f2..2ef26502193400 100644
--- a/lldb/include/lldb/API/SBProcess.h
+++ b/lldb/include/lldb/API/SBProcess.h
@@ -407,30 +407,44 @@ class LLDB_API SBProcess {
   ///     the process isn't loaded from a core file.
   lldb::SBFileSpec GetCoreFile();
 
-  /// Get the current address mask that can be applied to addresses
+  /// \{
+  /// \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.
+  /// On AArch32 code with arm+thumb code, 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.
+  ///
+  /// \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 like 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
-  ///     lldb may have different address masks for code and data
-  ///     addresses.  Either can be requested, or most commonly,
-  ///     eAddressMaskTypeAny can be requested and the least specific
-  ///     mask will be fetched.  e.g. on a target where instructions
-  ///     are word aligned, the Code mask might clear the low 2 bits.
+  ///     See \ref Mask Address Methods descripton 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
-  ///     Specify whether the address mask for high or low address spaces
-  ///     is requested.
-  ///     It is highly unusual to have different address masks in high
-  ///     or low memory, and by default the eAddressMaskRangeLow is the
-  ///     only one used for both types of addresses, the default value for
-  ///     this argument is the correct one.
-  ///
-  ///     On some architectures like AArch64, it is possible to have
-  ///     different page table setups for low and high memory, so different
-  ///     numbers of bits relevant to addressing, and it is possible to have
-  ///     a program running in one half of memory and accessing the other
-  ///     as heap, etc.  In that case the eAddressMaskRangeLow and
-  ///     eAddressMaskRangeHigh will have different masks that must be handled.
+  ///     See \ref Mask Address Methods descripton 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
@@ -443,32 +457,18 @@ class LLDB_API SBProcess {
   /// before reading from memory.
   ///
   /// \param[in] type
-  ///     lldb may have different address masks for code and data
-  ///     addresses.  Either can be set, or most commonly,
-  ///     eAddressMaskTypeAll can be set for both types of addresses.
-  ///     An example where they could be different is a target where
-  ///     instructions are word aligned, so the low 2 bits are always
-  ///     zero.
+  ///     See \ref Mask Address Methods descripton 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
-  ///     Specify whether the address mask for high or low address spaces
-  ///     is being set.
-  ///     It is highly unusual to have different address masks in high
-  ///     or low memory, and by default the eAddressMaskRangeLow is the
-  ///     only one used for both types of addresses, the default value for
-  ///     this argument is the correct one.
-  ///
-  ///     On some architectures like AArch64, it is possible to have
-  ///     different page table setups for low and high memory, so different
-  ///     numbers of bits relevant to addressing, and it is possible to have
-  ///     a program running in one half of memory and accessing the other
-  ///     as heap, etc.  In that case the eAddressMaskRangeLow and
-  ///     eAddressMaskRangeHigh will have different masks that must be
-  ///     specified.
+  ///     See \ref Mask Address Methods descripton 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);
@@ -476,37 +476,25 @@ class LLDB_API SBProcess {
   /// Set the number of bits used for addressing in this Process.
   ///
   /// In some environments, the number of bits that are used for addressing
-  /// is the natural representation insted of a mask; this method calculates
-  /// the addressing mask that lldb uses internally from that number.
+  /// is the natural representation instead of a mask, but lldb
+  /// internally represents this as a mask.  This method calculates
+  /// the addressing mask that lldb uses that number of addressable bits.
   ///
   /// \param[in] type
-  ///     lldb may have different address masks for code and data
-  ///     addresses.  Either can be set, or most commonly,
-  ///     eAddressMaskTypeAll can be set for both types of addresses.
-  ///     An example where they could be different is a target where
-  ///     instructions are word aligned, so the low 2 bits are always
-  ///     zero.
+  ///     See \ref Mask Address Methods descripton 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.  e.g. the low 42
-  ///     bits may be the only ones used for addressing, and high bits may
-  ///     store metadata and should be ignored by lldb.
+  ///     Number of bits that are used for addressing.
+  ///     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
-  ///     Specify whether the address mask for high or low address spaces
-  ///     is being set.
-  ///     It is highly unusual to have different address masks in high
-  ///     or low memory, and by default the eAddressMaskRangeLow is the
-  ///     only one used for both types of addresses, the default value for
-  ///     this argument is the correct one.
-  ///
-  ///     On some architectures like AArch64, it is possible to have
-  ///     different page table setups for low and high memory, so different
-  ///     numbers of bits relevant to addressing, and it is possible to have
-  ///     a program running in one half of memory and accessing the other
-  ///     as heap, etc.  In that case the eAddressMaskRangeLow and
-  ///     eAddressMaskRangeHigh will have different masks that must be
-  ///     specified.
+  ///     See \ref Mask Address Methods descripton 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);
@@ -522,13 +510,13 @@ class LLDB_API SBProcess {
   ///     The address that should be cleared of non-addressable bits.
   ///
   /// \param[in] type
-  ///     If the address is known to be a code address (address of a function,
-  ///     for example), eAddressMaskTypeCode may be passed, which may have
-  ///     stricter address clearing than data addresses e.g. the low 2 bits
-  ///     being unused for code addresses on AArch64.
+  ///     See \ref Mask Address Methods descripton 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.
   ///
diff --git a/lldb/include/lldb/lldb-enumerations.h b/lldb/include/lldb/lldb-enumerations.h
index 853370bf5eb515..646f7bfda98475 100644
--- a/lldb/include/lldb/lldb-enumerations.h
+++ b/lldb/include/lldb/lldb-enumerations.h
@@ -1323,6 +1323,7 @@ enum SymbolDownload {
   eSymbolDownloadForeground = 2,
 };
 
+/// Used in the SBProcess AddressMask/FixAddress methods.
 enum AddressMaskType {
   eAddressMaskTypeCode = 0,
   eAddressMaskTypeData,
@@ -1330,6 +1331,7 @@ enum AddressMaskType {
   eAddressMaskTypeAll = eAddressMaskTypeAny
 };
 
+/// Used in the SBProcess AddressMask/FixAddress methods.
 enum AddressMaskRange {
   eAddressMaskRangeLow = 0,
   eAddressMaskRangeHigh,

>From dbed95d5af61e8156c161f8880517daa8a5c3ead Mon Sep 17 00:00:00 2001
From: Jason Molenda <jmolenda at apple.com>
Date: Wed, 28 Feb 2024 16:35:52 -0800
Subject: [PATCH 3/4] Fix typeos spotted by Will, update SetAddressableBits doc

---
 lldb/include/lldb/API/SBProcess.h | 23 ++++++++++++-----------
 1 file changed, 12 insertions(+), 11 deletions(-)

diff --git a/lldb/include/lldb/API/SBProcess.h b/lldb/include/lldb/API/SBProcess.h
index 2ef26502193400..13b69508112a8c 100644
--- a/lldb/include/lldb/API/SBProcess.h
+++ b/lldb/include/lldb/API/SBProcess.h
@@ -437,12 +437,12 @@ class LLDB_API SBProcess {
   /// before reading from memory.
   ///
   /// \param[in] type
-  ///     See \ref Mask Address Methods descripton of this argument.
+  ///     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 descripton of this argument.
+  ///     See \ref Mask Address Methods description of this argument.
   ///     This will default to eAddressMaskRangeLow which is the
   ///     only set of masks used normally.
   ///
@@ -457,7 +457,7 @@ class LLDB_API SBProcess {
   /// before reading from memory.
   ///
   /// \param[in] type
-  ///     See \ref Mask Address Methods descripton of this argument.
+  ///     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.
   ///
@@ -466,7 +466,7 @@ class LLDB_API SBProcess {
   ///     should be set to 1 in the mask.
   ///
   /// \param[in] addr_range
-  ///     See \ref Mask Address Methods descripton of this argument.
+  ///     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(
@@ -475,13 +475,14 @@ class LLDB_API SBProcess {
 
   /// Set the number of bits used for addressing in this Process.
   ///
-  /// In some environments, the number of bits that are used for addressing
-  /// is the natural representation instead of a mask, but lldb
-  /// internally represents this as a mask.  This method calculates
-  /// the addressing mask that lldb uses that number of addressable bits.
+  /// 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 descripton of this argument.
+  ///     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.
   ///
@@ -492,7 +493,7 @@ class LLDB_API SBProcess {
   ///     metadata like pointer authentication, Type Byte Ignore, etc.
   ///
   /// \param[in] addr_range
-  ///     See \ref Mask Address Methods descripton of this argument.
+  ///     See \ref Mask Address Methods description of this argument.
   ///     This will default to eAddressMaskRangeLow which is the
   ///     only set of masks used normally.
   void
@@ -510,7 +511,7 @@ class LLDB_API SBProcess {
   ///     The address that should be cleared of non-addressable bits.
   ///
   /// \param[in] type
-  ///     See \ref Mask Address Methods descripton of this argument.
+  ///     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

>From dceaef27675b724309f353aa22999563cf036cd3 Mon Sep 17 00:00:00 2001
From: Jason Molenda <github-mail at molenda.com>
Date: Thu, 29 Feb 2024 14:04:56 -0800
Subject: [PATCH 4/4] Apply suggestions from code review

Add Will's good copyedit suggestions.

Co-authored-by: Will Hawkins <whh8b at obs.cr>
---
 lldb/include/lldb/API/SBProcess.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/lldb/include/lldb/API/SBProcess.h b/lldb/include/lldb/API/SBProcess.h
index 13b69508112a8c..e2a6922724f005 100644
--- a/lldb/include/lldb/API/SBProcess.h
+++ b/lldb/include/lldb/API/SBProcess.h
@@ -426,7 +426,7 @@ class LLDB_API SBProcess {
   /// 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 like AArch64, it is possible to have
+  /// 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
@@ -488,8 +488,8 @@ class LLDB_API SBProcess {
   ///
   /// \param[in] num_bits
   ///     Number of bits that are used for addressing.
-  ///     A value of 42 indicates that the low 42 bits are relevant for
-  ///     addressing, and that higher order bits may be used for various
+  ///     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



More information about the lldb-commits mailing list