[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"