Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add AddressRange to SB API #92014

Merged
merged 1 commit into from
May 28, 2024
Merged

Add AddressRange to SB API #92014

merged 1 commit into from
May 28, 2024

Conversation

mbucko
Copy link
Contributor

@mbucko mbucko commented May 13, 2024

Summary:
This adds new SB API calls and classes to allow a user of the SB API to obtain an address range from SBFunction and SBBlock.

Test Plan:
llvm-lit -sv llvm-project/lldb/test/API/python_api/address_range/TestAddressRange.py

Reviewers: clayborg

Subscribers: lldb-commits

Tasks:

Tags:

@mbucko mbucko requested a review from JDevlieghere as a code owner May 13, 2024 19:18
@llvmbot llvmbot added the lldb label May 13, 2024
@llvmbot
Copy link
Collaborator

llvmbot commented May 13, 2024

@llvm/pr-subscribers-lldb

Author: Miro Bucko (mbucko)

Changes

Summary:
This adds new SB API calls and classes to allow a user of the SB API to obtain an address range from SBFunction and SBBlock.

Test Plan:

Reviewers: clayborg

Subscribers: lldb-commits

Tasks:

Tags:


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

23 Files Affected:

  • (modified) lldb/bindings/headers.swig (+2)
  • (added) lldb/bindings/interface/SBAddressRangeDocstrings.i (+3)
  • (added) lldb/bindings/interface/SBAddressRangeListDocstrings.i (+3)
  • (added) lldb/bindings/interface/SBAddressRangeListExtensions.i (+13)
  • (modified) lldb/bindings/interfaces.swig (+2)
  • (modified) lldb/include/lldb/API/LLDB.h (+2)
  • (modified) lldb/include/lldb/API/SBAddress.h (+1)
  • (added) lldb/include/lldb/API/SBAddressRange.h (+63)
  • (added) lldb/include/lldb/API/SBAddressRangeList.h (+57)
  • (modified) lldb/include/lldb/API/SBBlock.h (+3)
  • (modified) lldb/include/lldb/API/SBDefines.h (+2)
  • (modified) lldb/include/lldb/API/SBFunction.h (+3)
  • (modified) lldb/include/lldb/Core/AddressRange.h (+8)
  • (modified) lldb/include/lldb/lldb-forward.h (+3)
  • (modified) lldb/source/API/CMakeLists.txt (+2)
  • (added) lldb/source/API/SBAddressRange.cpp (+78)
  • (added) lldb/source/API/SBAddressRangeList.cpp (+131)
  • (modified) lldb/source/API/SBBlock.cpp (+10)
  • (modified) lldb/source/API/SBFunction.cpp (+11)
  • (modified) lldb/source/Core/AddressRange.cpp (+4)
  • (added) lldb/test/API/python_api/address_range/Makefile (+3)
  • (added) lldb/test/API/python_api/address_range/TestAddressRange.py (+124)
  • (added) lldb/test/API/python_api/address_range/main.cpp (+5)
diff --git a/lldb/bindings/headers.swig b/lldb/bindings/headers.swig
index e8d0cda288141..2b53eefc8568b 100644
--- a/lldb/bindings/headers.swig
+++ b/lldb/bindings/headers.swig
@@ -8,6 +8,8 @@
 %{
 #include "lldb/lldb-public.h"
 #include "lldb/API/SBAddress.h"
+#include "lldb/API/SBAddressRange.h"
+#include "lldb/API/SBAddressRangeList.h"
 #include "lldb/API/SBAttachInfo.h"
 #include "lldb/API/SBBlock.h"
 #include "lldb/API/SBBreakpoint.h"
diff --git a/lldb/bindings/interface/SBAddressRangeDocstrings.i b/lldb/bindings/interface/SBAddressRangeDocstrings.i
new file mode 100644
index 0000000000000..650195704d73e
--- /dev/null
+++ b/lldb/bindings/interface/SBAddressRangeDocstrings.i
@@ -0,0 +1,3 @@
+%feature("docstring",
+"API clients can get address range information."
+) lldb::SBAddressRange;
diff --git a/lldb/bindings/interface/SBAddressRangeListDocstrings.i b/lldb/bindings/interface/SBAddressRangeListDocstrings.i
new file mode 100644
index 0000000000000..e4b96b9ca5931
--- /dev/null
+++ b/lldb/bindings/interface/SBAddressRangeListDocstrings.i
@@ -0,0 +1,3 @@
+%feature("docstring",
+"Represents a list of :py:class:`SBAddressRange`."
+) lldb::SBAddressRangeList;
diff --git a/lldb/bindings/interface/SBAddressRangeListExtensions.i b/lldb/bindings/interface/SBAddressRangeListExtensions.i
new file mode 100644
index 0000000000000..781780b15e877
--- /dev/null
+++ b/lldb/bindings/interface/SBAddressRangeListExtensions.i
@@ -0,0 +1,13 @@
+%extend lldb::SBAddressRangeList {
+#ifdef SWIGPYTHON
+    %pythoncode%{
+    def __len__(self):
+      '''Return the number of address ranges in a lldb.SBAddressRangeList object.'''
+      return self.GetSize()
+
+    def __iter__(self):
+      '''Iterate over all the address ranges in a lldb.SBAddressRangeList object.'''
+      return lldb_iter(self, 'GetSize', 'GetAddressRangeAtIndex')
+    %}
+#endif
+}
diff --git a/lldb/bindings/interfaces.swig b/lldb/bindings/interfaces.swig
index a31a0b4af1eb6..b9aae318d0684 100644
--- a/lldb/bindings/interfaces.swig
+++ b/lldb/bindings/interfaces.swig
@@ -86,6 +86,8 @@
 
 /* API headers */
 %include "lldb/API/SBAddress.h"
+%include "lldb/API/SBAddressRange.h"
+%include "lldb/API/SBAddressRangeList.h"
 %include "lldb/API/SBAttachInfo.h"
 %include "lldb/API/SBBlock.h"
 %include "lldb/API/SBBreakpoint.h"
diff --git a/lldb/include/lldb/API/LLDB.h b/lldb/include/lldb/API/LLDB.h
index b256544326a22..d8cc9f5067fe9 100644
--- a/lldb/include/lldb/API/LLDB.h
+++ b/lldb/include/lldb/API/LLDB.h
@@ -10,6 +10,8 @@
 #define LLDB_API_LLDB_H
 
 #include "lldb/API/SBAddress.h"
+#include "lldb/API/SBAddressRange.h"
+#include "lldb/API/SBAddressRangeList.h"
 #include "lldb/API/SBAttachInfo.h"
 #include "lldb/API/SBBlock.h"
 #include "lldb/API/SBBreakpoint.h"
diff --git a/lldb/include/lldb/API/SBAddress.h b/lldb/include/lldb/API/SBAddress.h
index 5e5f355ccc390..430dad4862dbf 100644
--- a/lldb/include/lldb/API/SBAddress.h
+++ b/lldb/include/lldb/API/SBAddress.h
@@ -86,6 +86,7 @@ class LLDB_API SBAddress {
   lldb::SBLineEntry GetLineEntry();
 
 protected:
+  friend class SBAddressRange;
   friend class SBBlock;
   friend class SBBreakpoint;
   friend class SBBreakpointLocation;
diff --git a/lldb/include/lldb/API/SBAddressRange.h b/lldb/include/lldb/API/SBAddressRange.h
new file mode 100644
index 0000000000000..2ff5b29593e58
--- /dev/null
+++ b/lldb/include/lldb/API/SBAddressRange.h
@@ -0,0 +1,63 @@
+//===-- SBAddressRange.h ----------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_API_SBADDRESSRANGE_H
+#define LLDB_API_SBADDRESSRANGE_H
+
+#include "lldb/API/SBDefines.h"
+
+namespace lldb {
+
+class LLDB_API SBAddressRange {
+public:
+  SBAddressRange();
+
+  SBAddressRange(const lldb::SBAddressRange &rhs);
+
+  SBAddressRange(lldb::addr_t file_addr, lldb::addr_t byte_size);
+
+  ~SBAddressRange();
+
+  const lldb::SBAddressRange &operator=(const lldb::SBAddressRange &rhs);
+
+  void Clear();
+
+  bool IsValid() const;
+
+  /// Get the base address of the range.
+  ///
+  /// \return
+  ///     Base address object.
+  lldb::SBAddress GetBaseAddress() const;
+
+  /// Get the byte size of this range.
+  ///
+  /// \return
+  ///     The size in bytes of this address range.
+  lldb::addr_t GetByteSize() const;
+
+protected:
+  friend class SBAddressRangeList;
+  friend class SBBlock;
+  friend class SBFunction;
+
+  lldb_private::AddressRange &ref();
+
+  const lldb_private::AddressRange &ref() const;
+
+private:
+  AddressRangeUP m_opaque_up;
+};
+
+#ifndef SWIG
+bool LLDB_API operator==(const SBAddressRange &lhs, const SBAddressRange &rhs);
+#endif
+
+} // namespace lldb
+
+#endif // LLDB_API_SBADDRESSRANGE_H
diff --git a/lldb/include/lldb/API/SBAddressRangeList.h b/lldb/include/lldb/API/SBAddressRangeList.h
new file mode 100644
index 0000000000000..81dab4a88d189
--- /dev/null
+++ b/lldb/include/lldb/API/SBAddressRangeList.h
@@ -0,0 +1,57 @@
+//===-- SBAddressRangeList.h ------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_API_SBADDRESSRANGELIST_H
+#define LLDB_API_SBADDRESSRANGELIST_H
+
+#include <memory>
+
+#include "lldb/API/SBDefines.h"
+
+class AddressRangeListImpl;
+
+namespace lldb {
+
+class LLDB_API SBAddressRangeList {
+public:
+  SBAddressRangeList();
+
+  SBAddressRangeList(const lldb::SBAddressRangeList &rhs);
+
+  ~SBAddressRangeList();
+
+  const lldb::SBAddressRangeList &operator=(const lldb::SBAddressRangeList &rhs);
+
+  uint32_t GetSize() const;
+
+  void Clear();
+
+  bool GetAddressRangeAtIndex(uint64_t idx, SBAddressRange &addr_range);
+
+  void Append(const lldb::SBAddressRange &addr_range);
+
+  void Append(const lldb::SBAddressRangeList &addr_range_list);
+
+protected:
+  const AddressRangeListImpl *operator->() const;
+
+  const AddressRangeListImpl &operator*() const;
+  
+private:
+  friend class SBProcess;
+
+  lldb_private::AddressRanges &ref();
+
+  const lldb_private::AddressRanges &ref() const;
+
+  std::unique_ptr<AddressRangeListImpl> m_opaque_up;
+};
+
+} // namespace lldb
+
+#endif // LLDB_API_SBADDRESSRANGELIST_H
diff --git a/lldb/include/lldb/API/SBBlock.h b/lldb/include/lldb/API/SBBlock.h
index 2570099f7652f..1071fe1ad0802 100644
--- a/lldb/include/lldb/API/SBBlock.h
+++ b/lldb/include/lldb/API/SBBlock.h
@@ -9,6 +9,7 @@
 #ifndef LLDB_API_SBBLOCK_H
 #define LLDB_API_SBBLOCK_H
 
+#include "lldb/API/SBAddressRange.h"
 #include "lldb/API/SBDefines.h"
 #include "lldb/API/SBFrame.h"
 #include "lldb/API/SBTarget.h"
@@ -52,6 +53,8 @@ class LLDB_API SBBlock {
 
   lldb::SBAddress GetRangeEndAddress(uint32_t idx);
 
+  lldb::SBAddressRange GetRangeAtIndex(uint32_t idx);
+
   uint32_t GetRangeIndexForBlockAddress(lldb::SBAddress block_addr);
 
   lldb::SBValueList GetVariables(lldb::SBFrame &frame, bool arguments,
diff --git a/lldb/include/lldb/API/SBDefines.h b/lldb/include/lldb/API/SBDefines.h
index 1181920677b46..87c0a1c3661ca 100644
--- a/lldb/include/lldb/API/SBDefines.h
+++ b/lldb/include/lldb/API/SBDefines.h
@@ -43,6 +43,8 @@
 namespace lldb {
 
 class LLDB_API SBAddress;
+class LLDB_API SBAddressRange;
+class LLDB_API SBAddressRangeList;
 class LLDB_API SBAttachInfo;
 class LLDB_API SBBlock;
 class LLDB_API SBBreakpoint;
diff --git a/lldb/include/lldb/API/SBFunction.h b/lldb/include/lldb/API/SBFunction.h
index 71b372a818e4b..0e1f8b1cd15a0 100644
--- a/lldb/include/lldb/API/SBFunction.h
+++ b/lldb/include/lldb/API/SBFunction.h
@@ -10,6 +10,7 @@
 #define LLDB_API_SBFUNCTION_H
 
 #include "lldb/API/SBAddress.h"
+#include "lldb/API/SBAddressRange.h"
 #include "lldb/API/SBDefines.h"
 #include "lldb/API/SBInstructionList.h"
 
@@ -44,6 +45,8 @@ class LLDB_API SBFunction {
 
   lldb::SBAddress GetEndAddress();
 
+  lldb::SBAddressRange GetRange();
+
   const char *GetArgumentName(uint32_t arg_idx);
 
   uint32_t GetPrologueByteSize();
diff --git a/lldb/include/lldb/Core/AddressRange.h b/lldb/include/lldb/Core/AddressRange.h
index 4a33c2d795876..503d6e862f831 100644
--- a/lldb/include/lldb/Core/AddressRange.h
+++ b/lldb/include/lldb/Core/AddressRange.h
@@ -86,6 +86,8 @@ class AddressRange {
   /// (LLDB_INVALID_ADDRESS) and a zero byte size.
   void Clear();
 
+  bool IsValid() const;
+
   /// Check if a section offset address is contained in this range.
   ///
   /// \param[in] so_addr
@@ -242,6 +244,12 @@ class AddressRange {
   lldb::addr_t m_byte_size = 0; ///< The size in bytes of this address range.
 };
 
+// Forward-declarable wrapper.
+class AddressRanges : public std::vector<lldb_private::AddressRange> {
+public:
+  using std::vector<lldb_private::AddressRange>::vector;
+};
+
 } // namespace lldb_private
 
 #endif // LLDB_CORE_ADDRESSRANGE_H
diff --git a/lldb/include/lldb/lldb-forward.h b/lldb/include/lldb/lldb-forward.h
index 10ba921b9dac8..6d880b4da03c9 100644
--- a/lldb/include/lldb/lldb-forward.h
+++ b/lldb/include/lldb/lldb-forward.h
@@ -19,6 +19,8 @@ class ASTResultSynthesizer;
 class ASTStructExtractor;
 class Address;
 class AddressRange;
+class AddressRanges;
+class AddressRangeList;
 class AddressResolver;
 class ArchSpec;
 class Architecture;
@@ -308,6 +310,7 @@ template <unsigned N> class StreamBuffer;
 namespace lldb {
 
 typedef std::shared_ptr<lldb_private::ABI> ABISP;
+typedef std::unique_ptr<lldb_private::AddressRange> AddressRangeUP;
 typedef std::shared_ptr<lldb_private::Baton> BatonSP;
 typedef std::shared_ptr<lldb_private::Block> BlockSP;
 typedef std::shared_ptr<lldb_private::Breakpoint> BreakpointSP;
diff --git a/lldb/source/API/CMakeLists.txt b/lldb/source/API/CMakeLists.txt
index aa31caddfde3a..ce53dc6c635b4 100644
--- a/lldb/source/API/CMakeLists.txt
+++ b/lldb/source/API/CMakeLists.txt
@@ -38,6 +38,8 @@ add_custom_target(lldb-sbapi-dwarf-enums
 
 add_lldb_library(liblldb SHARED ${option_framework}
   SBAddress.cpp
+  SBAddressRange.cpp
+  SBAddressRangeList.cpp
   SBAttachInfo.cpp
   SBBlock.cpp
   SBBreakpoint.cpp
diff --git a/lldb/source/API/SBAddressRange.cpp b/lldb/source/API/SBAddressRange.cpp
new file mode 100644
index 0000000000000..8fce0efb3e3be
--- /dev/null
+++ b/lldb/source/API/SBAddressRange.cpp
@@ -0,0 +1,78 @@
+//===-- SBAddressRange.cpp ------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/API/SBAddressRange.h"
+#include "lldb/API/SBAddress.h"
+#include "lldb/Core/AddressRange.h"
+#include "lldb/Utility/Instrumentation.h"
+#include "Utils.h"
+#include <cstddef>
+#include <memory>
+
+using namespace lldb;
+using namespace lldb_private;
+
+SBAddressRange::SBAddressRange()
+    : m_opaque_up(std::make_unique<AddressRange>()) {
+  LLDB_INSTRUMENT_VA(this);
+}
+
+SBAddressRange::SBAddressRange(const SBAddressRange &rhs) {
+  LLDB_INSTRUMENT_VA(this, rhs);
+
+  m_opaque_up = clone(rhs.m_opaque_up);
+}
+
+SBAddressRange::SBAddressRange(lldb::addr_t file_addr, lldb::addr_t byte_size)
+  : m_opaque_up(std::make_unique<AddressRange>(file_addr, byte_size)) {
+  LLDB_INSTRUMENT_VA(this, file_addr, byte_size);
+}
+
+SBAddressRange::~SBAddressRange() = default;
+
+const SBAddressRange &SBAddressRange::operator=(const SBAddressRange &rhs) {
+  LLDB_INSTRUMENT_VA(this, rhs);
+
+  if (this != &rhs)
+    m_opaque_up = clone(rhs.m_opaque_up);
+  return *this;
+}
+
+void SBAddressRange::Clear() {
+  LLDB_INSTRUMENT_VA(this);
+
+  m_opaque_up.reset();
+}
+
+bool SBAddressRange::IsValid() const {
+  return m_opaque_up && m_opaque_up->IsValid();
+}
+
+lldb::SBAddress SBAddressRange::GetBaseAddress() const {
+  LLDB_INSTRUMENT_VA(this);
+
+  assert(m_opaque_up.get() && "AddressRange is NULL");
+  return lldb::SBAddress(m_opaque_up->GetBaseAddress());
+}
+
+lldb::addr_t SBAddressRange::GetByteSize() const {
+  LLDB_INSTRUMENT_VA(this);
+
+  assert(m_opaque_up.get() && "AddressRange is NULL");
+  return m_opaque_up->GetByteSize();
+}
+
+AddressRange &SBAddressRange::ref() {
+  assert(m_opaque_up.get() && "AddressRange is NULL");
+  return *m_opaque_up;
+}
+
+const AddressRange &SBAddressRange::ref() const {
+  assert(m_opaque_up.get() && "AddressRange is NULL");
+  return *m_opaque_up;
+}
diff --git a/lldb/source/API/SBAddressRangeList.cpp b/lldb/source/API/SBAddressRangeList.cpp
new file mode 100644
index 0000000000000..6226c4659a0a6
--- /dev/null
+++ b/lldb/source/API/SBAddressRangeList.cpp
@@ -0,0 +1,131 @@
+
+//===-- SBAddressRangeList.cpp --------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/API/SBAddressRangeList.h"
+#include "lldb/API/SBAddressRange.h"
+#include "lldb/Core/AddressRange.h"
+#include "lldb/Utility/Instrumentation.h"
+#include "Utils.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+class AddressRangeListImpl {
+public:
+  AddressRangeListImpl() : m_ranges() {}
+
+  AddressRangeListImpl(const AddressRangeListImpl &rhs) = default;
+
+  AddressRangeListImpl &operator=(const AddressRangeListImpl &rhs) {
+    if (this == &rhs)
+      return *this;
+    m_ranges = rhs.m_ranges;
+    return *this;
+  }
+
+  size_t GetSize() const { return m_ranges.size(); }
+
+  void Reserve(size_t capacity) { return m_ranges.reserve(capacity); }
+
+  void Append(const AddressRange &sb_region) {
+    m_ranges.emplace_back(sb_region);
+  }
+
+  void Append(const AddressRangeListImpl &list) {
+    Reserve(GetSize() + list.GetSize());
+
+    for (const auto &range : list.m_ranges)
+      Append(range);
+  }
+
+  void Clear() { m_ranges.clear(); }
+
+  bool GetAddressRangeAtIndex(size_t index, AddressRange &addr_range) {
+    if (index >= GetSize())
+      return false;
+    addr_range = m_ranges[index];
+    return true;
+  }
+
+  AddressRanges &Ref() { return m_ranges; }
+
+  const AddressRanges &Ref() const { return m_ranges; }
+
+private:
+  AddressRanges m_ranges;
+};
+
+AddressRanges &SBAddressRangeList::ref() { return m_opaque_up->Ref(); }
+
+const AddressRanges &SBAddressRangeList::ref() const {
+  return m_opaque_up->Ref();
+}
+
+SBAddressRangeList::SBAddressRangeList()
+    : m_opaque_up(new AddressRangeListImpl()) {
+  LLDB_INSTRUMENT_VA(this);
+}
+
+SBAddressRangeList::SBAddressRangeList(
+    const SBAddressRangeList &rhs)
+    : m_opaque_up(new AddressRangeListImpl(*rhs.m_opaque_up)) {
+  LLDB_INSTRUMENT_VA(this, rhs);
+}
+
+SBAddressRangeList::~SBAddressRangeList() = default;
+
+const SBAddressRangeList &SBAddressRangeList::
+operator=(const SBAddressRangeList &rhs) {
+  LLDB_INSTRUMENT_VA(this, rhs);
+
+  if (this != &rhs) {
+    *m_opaque_up = *rhs.m_opaque_up;
+  }
+  return *this;
+}
+
+uint32_t SBAddressRangeList::GetSize() const {
+  LLDB_INSTRUMENT_VA(this);
+
+  return m_opaque_up->GetSize();
+}
+
+bool SBAddressRangeList::GetAddressRangeAtIndex(
+    uint64_t idx, SBAddressRange &addr_range) {
+  LLDB_INSTRUMENT_VA(this, idx, addr_range);
+
+  return m_opaque_up->GetAddressRangeAtIndex(idx, addr_range.ref());
+}
+
+void SBAddressRangeList::Clear() {
+  LLDB_INSTRUMENT_VA(this);
+
+  m_opaque_up->Clear();
+}
+
+void SBAddressRangeList::Append(const SBAddressRange &sb_addr_range) {
+  LLDB_INSTRUMENT_VA(this, sb_addr_range);
+
+  m_opaque_up->Append(sb_addr_range.ref());
+}
+
+void SBAddressRangeList::Append(const SBAddressRangeList &sb_addr_range_list) {
+  LLDB_INSTRUMENT_VA(this, sb_addr_range_list);
+
+  m_opaque_up->Append(*sb_addr_range_list);
+}
+
+const AddressRangeListImpl *SBAddressRangeList::operator->() const {
+  return m_opaque_up.get();
+}
+
+const AddressRangeListImpl &SBAddressRangeList::operator*() const {
+  assert(m_opaque_up.get());
+  return *m_opaque_up;
+}
diff --git a/lldb/source/API/SBBlock.cpp b/lldb/source/API/SBBlock.cpp
index 7d7565340836b..0726777ddd6e9 100644
--- a/lldb/source/API/SBBlock.cpp
+++ b/lldb/source/API/SBBlock.cpp
@@ -219,6 +219,16 @@ lldb::SBAddress SBBlock::GetRangeEndAddress(uint32_t idx) {
   return sb_addr;
 }
 
+lldb::SBAddressRange SBBlock::GetRangeAtIndex(uint32_t idx) {
+  LLDB_INSTRUMENT_VA(this, idx);
+
+  lldb::SBAddressRange sb_range;
+  if (m_opaque_ptr) {
+    m_opaque_ptr->GetRangeAtIndex(idx, sb_range.ref());
+  }
+  return sb_range;
+}
+
 uint32_t SBBlock::GetRangeIndexForBlockAddress(lldb::SBAddress block_addr) {
   LLDB_INSTRUMENT_VA(this, block_addr);
 
diff --git a/lldb/source/API/SBFunction.cpp b/lldb/source/API/SBFunction.cpp
index a01c7f79bbd31..4f916357370d3 100644
--- a/lldb/source/API/SBFunction.cpp
+++ b/lldb/source/API/SBFunction.cpp
@@ -160,6 +160,17 @@ SBAddress SBFunction::GetEndAddress() {
   return addr;
 }
 
+lldb::SBAddressRange SBFunction::GetRange() {
+  LLDB_INSTRUMENT_VA(this);
+  
+  lldb::SBAddressRange range;
+  if (m_opaque_ptr) {
+    range.ref() = m_opaque_ptr->GetAddressRange();
+  }
+
+  return range;
+}
+
 const char *SBFunction::GetArgumentName(uint32_t arg_idx) {
   LLDB_INSTRUMENT_VA(this, arg_idx);
 
diff --git a/lldb/source/Core/AddressRange.cpp b/lldb/source/Core/AddressRange.cpp
index 1830f2ccd47fe..e9fa1b8f72b53 100644
--- a/lldb/source/Core/AddressRange.cpp
+++ b/lldb/source/Core/AddressRange.cpp
@@ -145,6 +145,10 @@ void AddressRange::Clear() {
   m_byte_size = 0;
 }
 
+bool AddressRange::IsValid() const {
+  return m_base_addr.IsValid() && (m_byte_size > 0);
+}
+
 bool AddressRange::Dump(Stream *s, Target *target, Address::DumpStyle style,
                         Address::DumpStyle fallback_style) const {
   addr_t vmaddr = LLDB_INVALID_ADDRESS;
diff --git a/lldb/test/API/python_api/address_range/Makefile b/lldb/test/API/python_api/address_range/Makefile
new file mode 100644
index 0000000000000..99998b20bcb05
--- /dev/null
+++ b/lldb/test/API/python_api/address_range/Makefile
@@ -0,0 +1,3 @@
+CXX_SOURCES := main.cpp
+
+include Makefile.rules
diff --git a/lldb/test/API/python_api/address_range/TestAddressRange.py b/lldb/test/API/python_api/address_range/TestAddressRange.py
new file mode 100644
index 0000000000000..3f5e79a6ad1de
--- /dev/null
+++ b/lldb/test/API/python_api/address_range/TestAddressRange.py
@@ -0,0 +1,124 @@
+"""
+Test SBAddressRange APIs.
+"""
+
+import lldb
+from lldbsuite.test.lldbtest import *
+
+
+class AddressRangeTestCase(TestBase):
+    NO_DEBUG_INFO_TESTCASE = True
+
+    def test_address_range_default(self):
+        """Testing default constructor."""
+        empty_range = lldb.SBAddressRange()
+        self.assertEqual(empty_range.IsValid(), False)
+
+    def test_address_range_construction(self):
+        """Make sure the construction and getters work."""
+        range = lldb.SBAddressRange(0x00000400, 8)
+        self.assertEqual(range.IsValid(), True)
+        self.assertEqual(range.GetBaseAddress().GetOffset(), 0x00000400)
+        self.assertEqual(range.GetByteSize(), 8)
+
+    def test_address_range_clear(self):
+        """Make sure the clear method works."""
+        range = lldb.SBAddressRange(0x00000400, 8)
+        self.assertEqual(range.IsValid(), True)
+        self.assertEqual(range.GetBaseAddress().GetOffset(), 0x00000400)
+        self.assertEqual(range.GetByteSize(), 8)
+
+        range.Clear()
+        self.assertEqual(range.IsValid(), False)
+
+    def test_function(self):
+        """Make sure the range works in SBFunction APIs."""
+        self.build()
+        exe = self.getBuildArtifact("a.out")
+
+        # Create a target by the debugger.
+        target = self.dbg.CreateTarget(exe)
+        self.assertTrue(target, VALID_TARGET)
+
+        # Setup breakpoints in main
+        bp = target.BreakpointCreateByName("main", "a.out")
+        loc = bp.GetLocationAtIndex(0)
+        loc_addr = loc.GetAd...
[truncated]

Copy link

github-actions bot commented May 13, 2024

✅ With the latest revision this PR passed the C/C++ code formatter.

lldb/include/lldb/API/SBAddressRange.h Outdated Show resolved Hide resolved
lldb/include/lldb/API/SBAddressRange.h Outdated Show resolved Hide resolved
lldb/source/API/SBAddressRange.cpp Show resolved Hide resolved
lldb/source/API/SBAddressRange.cpp Outdated Show resolved Hide resolved
lldb/test/API/python_api/address_range/TestAddressRange.py Outdated Show resolved Hide resolved
lldb/include/lldb/API/SBAddressRangeList.h Outdated Show resolved Hide resolved
lldb/source/API/SBAddressRangeList.cpp Outdated Show resolved Hide resolved
lldb/include/lldb/Core/AddressRange.h Show resolved Hide resolved
lldb/include/lldb/API/SBAddressRangeList.h Outdated Show resolved Hide resolved
lldb/source/API/SBAddressRangeList.cpp Outdated Show resolved Hide resolved
@bulbazord
Copy link
Member

I forgot to ask, what is the motivation behind this change? Is there something you can't do with the SBAPI right now or that is better expressed with SBAddressRange and SBAddressRangeList?

lldb/include/lldb/API/SBAddressRange.h Outdated Show resolved Hide resolved
lldb/include/lldb/API/SBAddressRange.h Outdated Show resolved Hide resolved
lldb/include/lldb/API/SBAddressRange.h Show resolved Hide resolved

void Clear();

bool GetAddressRangeAtIndex(uint64_t idx, SBAddressRange &addr_range);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, please make this:

SBAddressRange GetAddressRangeAtIndex(uint64_t idx);

Easier to use in code and in python. Return a default constructed SBAddressRange if idx is out of range.

lldb/include/lldb/API/SBAddressRangeList.h Outdated Show resolved Hide resolved
lldb/source/API/SBAddressRange.cpp Outdated Show resolved Hide resolved
lldb/source/API/SBAddressRange.cpp Outdated Show resolved Hide resolved
lldb/source/API/SBAddressRangeList.cpp Outdated Show resolved Hide resolved
lldb/source/API/SBBlock.cpp Outdated Show resolved Hide resolved
lldb/test/API/python_api/address_range/main.cpp Outdated Show resolved Hide resolved
@mbucko
Copy link
Contributor Author

mbucko commented May 14, 2024

I forgot to ask, what is the motivation behind this change? Is there something you can't do with the SBAPI right now or that is better expressed with SBAddressRange and SBAddressRangeList?

Yes, I want to add the following API:

lldb::SBError SBProcess::FindInMemory(const SBAddressRangeList &ranges, const void *buf, uint64_t size, SBAddressRangeList &matches, size_t alignment);

@clayborg
Copy link
Collaborator

I forgot to ask, what is the motivation behind this change? Is there something you can't do with the SBAPI right now or that is better expressed with SBAddressRange and SBAddressRangeList?

Yes, I want to add the following API:

lldb::SBError SBProcess::FindInMemory(const SBAddressRangeList &ranges, const void *buf, uint64_t size, SBAddressRangeList &matches, size_t alignment);

Yeah, we have no SBProcess::FindMemory() API, but we do have a "memory find" command. We want to expose simple memory finds, and complex ones like above:

addr_t SBProcess::FindInMemory(SBAddressRange &range, const void *buf, uint64_t size, size_t alignment);
SBError SBProcess::FindInMemory(const SBAddressRangeList &ranges, const void *buf, uint64_t size, SBAddressRangeList &matches, size_t alignment);

We then want to plumb this through to the lldb_private::Process plug-ins so we can allow plug-ins to do things more efficiently. Mostly for core files where we could parallelize the memory search.

Copy link
Collaborator

@clayborg clayborg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We might want SBAddressRange and SBAddressRangeList to have methods:

  bool GetDescription(lldb::SBStream &description);

Then make sure we add stuff to the .i files so python str(<obj>) calls this. We do this in many other classes.

lldb/source/API/SBAddressRange.cpp Outdated Show resolved Hide resolved
lldb/include/lldb/API/SBAddressRangeList.h Outdated Show resolved Hide resolved
@mbucko mbucko force-pushed the address_range branch 4 times, most recently from c28e095 to 44871da Compare May 15, 2024 20:50
Comment on lines 56 to 58
lldb::SBAddressRange GetRangeAtIndex(uint32_t idx);

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would expose only SBAddressRangeList GetRanges(). No need for both

lldb/bindings/interface/SBAddressRangeListExtensions.i Outdated Show resolved Hide resolved
lldb/source/API/SBAddressRangeList.cpp Outdated Show resolved Hide resolved
lldb/include/lldb/Core/AddressRange.h Show resolved Hide resolved
@mbucko mbucko force-pushed the address_range branch 6 times, most recently from 1be2c95 to 939d42e Compare May 17, 2024 21:05
Copy link

github-actions bot commented May 17, 2024

✅ With the latest revision this PR passed the Python code formatter.

Copy link
Collaborator

@clayborg clayborg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See inlined comments as the SBAddressRange::GetDescription() could have crashed if we had an address with a no section and we did supply a valid target.

So changes needed:

  • add a test for a SBAddressRange object that is constructed with a SBAddress that has no section, just a raw address, and we print it out with a valid target (which won't be used because there is no section to resolve)
  • change address ranges to be emitted as [<start-addr>, <end-addr>) (end the range with a ) instead of a ] to indicate the range is not inclusive (for both the case where we have a module name and/or just dumping a load address range or file address range
  • make sure an address range that has a valid section, but that section isn't loaded into the target yet that your test can dump it before your run your debug program and see a.out[0x1000-0x2000), and then test once it is running and stopped and the section is loaded and it will print out using the [<start-load-addr>, <end-load-addr>)

lldb/include/lldb/API/SBAddressRange.h Outdated Show resolved Hide resolved
lldb/source/Core/AddressRange.cpp Outdated Show resolved Hide resolved
lldb/source/Core/AddressRange.cpp Outdated Show resolved Hide resolved
lldb/source/Core/AddressRange.cpp Outdated Show resolved Hide resolved
lldb/bindings/interface/SBAddressRangeListExtensions.i Outdated Show resolved Hide resolved
lldb/include/lldb/API/SBAddressRange.h Outdated Show resolved Hide resolved
lldb/include/lldb/API/SBAddressRangeList.h Show resolved Hide resolved
lldb/source/API/SBAddressRange.cpp Outdated Show resolved Hide resolved
lldb/source/API/SBAddressRangeList.cpp Outdated Show resolved Hide resolved
lldb/source/API/SBAddressRangeList.cpp Outdated Show resolved Hide resolved
lldb/source/API/SBAddressRangeList.cpp Outdated Show resolved Hide resolved
lldb/source/API/SBAddressRangeList.cpp Show resolved Hide resolved
@mbucko mbucko force-pushed the address_range branch 2 times, most recently from bcca842 to 74ddb1e Compare May 24, 2024 15:40
Copy link
Collaborator

@clayborg clayborg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On nit in the getitem python, but looks good! Thanks for all of the changes.

lldb/bindings/interface/SBAddressRangeListExtensions.i Outdated Show resolved Hide resolved
Summary:
This adds new SB API calls and classes to allow a user of the SB API to
obtain an address range from SBFunction and SBBlock.

Test Plan:
llvm-lit -sv llvm-project/lldb/test/API/python_api/address_range/TestAddressRange.py

Reviewers: clayborg

Subscribers: lldb-commits

Tasks:

Tags:
@clayborg clayborg merged commit 42944e4 into llvm:main May 28, 2024
5 checks passed
@DavidSpickett
Copy link
Collaborator

The new tests are flaky on Windows on Arm, I'm looking into it.

DavidSpickett added a commit that referenced this pull request May 29, 2024
The new tests added in #92014 have been flaky on Linaro's
Windows on Arm bot. They appear to be hitting a deadlock trying
to clean up the test process.

This only happens in async mode and I don't see why this test
case needs async mode, so the simple workaround is to stick to
sync mode.
@DavidSpickett
Copy link
Collaborator

The tests were hitting a deadlock trying to kill the test process in async debug mode. So I've just changed it to sync mode, as I didn't see any reason to be async here.

It's a symptom of something greater I expect but I don't have time to dig into it at the moment.

vg0204 pushed a commit to vg0204/llvm-project that referenced this pull request May 29, 2024
This adds new SB API calls and classes to allow a user of the SB API to obtain an address ranges from SBFunction and SBBlock.
vg0204 pushed a commit to vg0204/llvm-project that referenced this pull request May 29, 2024
The new tests added in llvm#92014 have been flaky on Linaro's
Windows on Arm bot. They appear to be hitting a deadlock trying
to clean up the test process.

This only happens in async mode and I don't see why this test
case needs async mode, so the simple workaround is to stick to
sync mode.
@Michael137
Copy link
Member

Michael137 commented May 29, 2024

FYI, the TestAddressRange tests are failing on the macOS buildbots: https://green.lab.llvm.org/job/llvm.org/view/LLDB/job/as-lldb-cmake/4764/execution/node/97/log/

======================================================================
FAIL: test_address_range_print_resolved (TestAddressRange.AddressRangeTestCase)
    Make sure the SBAddressRange can be printed when resolved.
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/ec2-user/jenkins/workspace/llvm.org/as-lldb-cmake/llvm-project/lldb/test/API/python_api/address_range/TestAddressRange.py", line 186, in test_address_range_print_resolved
    self.assertRegex(range_str, "^\[0x[0-9a-f]+\-0x[0-9a-f]+\)$")
AssertionError: Regex didn't match: '^\\[0x[0-9a-f]+\\-0x[0-9a-f]+\\)$' not found in 'a.out[0x100003f70-0x100003fa0)'

Seems like we just didn't account for the a.out prefix here? Though based on the comments in the tests the a.out was purposefully omitted from the pattern...

@mbucko
Copy link
Contributor Author

mbucko commented May 29, 2024

If the a.out is not there then the address was not resolved, I will investigate.

@Michael137
Copy link
Member

I'll revert this for now. Let me know if you need help reproducing the failure

Michael137 added a commit that referenced this pull request May 30, 2024
mbucko added a commit to mbucko/llvm-project that referenced this pull request May 30, 2024
Summary:
This adds new SB API calls and classes to allow a user of the SB API to
obtain an address range from SBFunction and SBBlock.
This is a second attempt to land the reverted PR llvm#92014.

Test Plan:
llvm-lit -sv llvm-project/lldb/test/API/python_api/address_range/TestAddressRange.py

Reviewers: clayborg

Subscribers: lldb-commits

Tasks:

Tags:
clayborg pushed a commit that referenced this pull request May 30, 2024
This adds new SB API calls and classes to allow a user of the SB API to obtain an address range from SBFunction and SBBlock. This is a second attempt to land the reverted PR #92014.
@mbucko mbucko deleted the address_range branch June 12, 2024 04:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants