[binutils-gdb] gdb/python: add property ranges to gdb.Block object

Jan Vrany via Gdb-cvs <[email protected]>
Newsgroups gmane.comp.gdb.cvs
Message-ID <[email protected]>
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=1a10ac99959e8d28694cb47d0632552e6feb03b2

commit 1a10ac99959e8d28694cb47d0632552e6feb03b2
Author: Jan Vrany <[email protected]>
Date:   Wed Mar 25 15:06:23 2026 +0000

    gdb/python: add property ranges to gdb.Block object
    
    This commit adds a new property - ranges - to gdb.Block object. It holds
    a tuple of ranges for that block. Each range is a tuple of (start, end)
    address. For contiguous blocks it contains only one range.
    
    Reviewed-By: Eli Zaretskii <[email protected]>
    Approved-By: Tom Tromey <[email protected]>

Diff:
---
 gdb/NEWS                              |  4 ++++
 gdb/doc/python.texi                   |  8 +++++++
 gdb/python/py-block.c                 | 39 +++++++++++++++++++++++++++++++++++
 gdb/testsuite/gdb.python/py-block.exp |  3 +++
 4 files changed, 54 insertions(+)

diff --git a/gdb/NEWS b/gdb/NEWS
index 03f46df5400..4cf91053c95 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -234,6 +234,10 @@ qExecAndArgs
      strings in the disassembler output can contain ANSI escape
      sequences to indicate styling.
 
+  ** New gdb.Block.ranges attribute.  This read only attribute contains
+     a tuple of pairs each representing a single range.  Contiguous blocks
+     have only one range.
+
 * Guile API
 
   ** Procedures 'memory-port-read-buffer-size',
diff --git a/gdb/doc/python.texi b/gdb/doc/python.texi
index d7718818def..e1e983726e8 100644
--- a/gdb/doc/python.texi
+++ b/gdb/doc/python.texi
@@ -6342,6 +6342,14 @@ One past the last address that appears in the block.  This attribute
 is not writable.
 @end defvar
 
+@defvar Block.ranges
+A tuple representing address ranges of the block.  Each range is represented
+as a pair (two-element tuple) where the first element is the start of the
+range and the second element is one past the last address that appears in
+the range. The order of ranges is unspecified.  Contiguous blocks have only
+one range.  This attribute is not writable.
+@end defvar
+
 @defvar Block.function
 The name of the block represented as a @code{gdb.Symbol}.  If the
 block is not named, then this attribute holds @code{None}.  This
diff --git a/gdb/python/py-block.c b/gdb/python/py-block.c
index 4d77242ca0d..6e4b662cc51 100644
--- a/gdb/python/py-block.c
+++ b/gdb/python/py-block.c
@@ -117,6 +117,43 @@ blpy_get_end (PyObject *self, void *closure)
   return gdb_py_object_from_ulongest (block->end ()).release ();
 }
 
+/* Implementation of gdb.Block.ranges.  */
+
+static PyObject *
+blpy_get_ranges (PyObject *self, void *closure)
+{
+  const struct block *block = nullptr;
+
+  BLPY_REQUIRE_VALID (self, block);
+
+  auto ranges = block->ranges ();
+
+  if (ranges.size () == 0)
+    return Py_BuildValue ("((" GDB_PY_LLU_ARG GDB_PY_LLU_ARG "))",
+			  (gdb_py_ulongest) block->start (),
+			  (gdb_py_ulongest) block->end ());
+  else
+    {
+      gdbpy_ref<> ranges_obj (PyTuple_New (ranges.size ()));
+      if (ranges_obj == nullptr)
+	return nullptr;
+
+      for (int i = 0; i < ranges.size (); i++)
+	{
+	  gdbpy_ref<> range_obj
+	    (Py_BuildValue ("(" GDB_PY_LLU_ARG GDB_PY_LLU_ARG ")",
+			    (gdb_py_ulongest) ranges[i].start (),
+			    (gdb_py_ulongest) ranges[i].end ()));
+	  if (range_obj == nullptr)
+	    return nullptr;
+
+	  PyTuple_SetItem (ranges_obj.get (), i, range_obj.release ());
+	}
+
+      return ranges_obj.release ();
+    }
+}
+
 static PyObject *
 blpy_get_function (PyObject *self, void *closure)
 {
@@ -564,6 +601,8 @@ static gdb_PyGetSetDef block_object_getset[] = {
     "Whether this block is a global block.", NULL },
   { "subblocks", blpy_get_subblocks, nullptr,
     "List of blocks contained in this block.", nullptr },
+  { "ranges", blpy_get_ranges, nullptr,
+    "List of address ranges for this block.", nullptr },
   { NULL }  /* Sentinel */
 };
 
diff --git a/gdb/testsuite/gdb.python/py-block.exp b/gdb/testsuite/gdb.python/py-block.exp
index b483d4b8a92..e4e309da05f 100644
--- a/gdb/testsuite/gdb.python/py-block.exp
+++ b/gdb/testsuite/gdb.python/py-block.exp
@@ -43,6 +43,9 @@ gdb_test "python print (block)" "<gdb.Block <anonymous> \{i, f, b\}>" \
 gdb_test "python print (block.function)" "None" "first anonymous block"
 gdb_test "python print (block.start)" "${decimal}" "check start not None"
 gdb_test "python print (block.end)" "${decimal}" "check end not None"
+gdb_test "python print (block.ranges)" \
+	 "\\(\\(${decimal}, ${decimal}\\)(,|(, (\\(${decimal}, ${decimal}\\))+))\\)" \
+	 "check ranges contains tuple of tuples"
 gdb_test "python print (block\['f'\].name == 'f')" "True" "check variable access"
 gdb_test "python print (block\['nonexistent'\])" ".*KeyError.*: 'nonexistent'.*" \
 	 "check nonexistent variable"
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.