diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index dbaf30e..e183693 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -23293,6 +23293,14 @@ exist in @value{GDBN} any longer. All other @code{gdb.Symtab_and_line} methods will throw an exception if it is invalid at the time the method is called. @end defmethod + +@defmethod Symtab_and_line find_line_pc_range +Attempt to find the range of program counter addresses for the +@code{line} attribute of the @code{Symtab_and_line} object. If +found, return a @code{Tuple} containing the start and end addresses +for the line. Otherwise (e.g., a line with no corresponding code or +not present in the debug info), return @code{None}. +@end defmethod @end table A @code{gdb.Symtab} object has the following attributes: diff --git a/gdb/python/py-symtab.c b/gdb/python/py-symtab.c index 107cdec..5ae1975 100644 --- a/gdb/python/py-symtab.c +++ b/gdb/python/py-symtab.c @@ -215,6 +215,46 @@ salpy_get_line (PyObject *self, void *closure) } static PyObject * +salpy_find_line_pc_range (PyObject *self, PyObject *args) +{ + struct symtab_and_line *sal = NULL; + CORE_ADDR start_pc, end_pc; + + SALPY_REQUIRE_VALID (self, sal); + + if (find_line_pc_range (*sal, &start_pc, &end_pc)) + { + PyObject *ret_tuple; + PyObject *start; + PyObject *end; + + ret_tuple = PyTuple_New (2); + if (!ret_tuple) + return NULL; + + start = gdb_py_long_from_ulongest (start_pc); + if (!start) + goto fail_ret; + if (PyTuple_SetItem (ret_tuple, 0, start) != 0) + goto fail_ret; + + end = gdb_py_long_from_ulongest (end_pc); + if (!end) + goto fail_ret; + if (PyTuple_SetItem (ret_tuple, 1, end) != 0) + goto fail_ret; + + return ret_tuple; + + fail_ret: + Py_DECREF (ret_tuple); + return NULL; + } + + return Py_None; +} + +static PyObject * salpy_get_symtab (PyObject *self, void *closure) { struct symtab_and_line *sal; @@ -526,6 +566,10 @@ static PyMethodDef sal_object_methods[] = { { "is_valid", salpy_is_valid, METH_NOARGS, "is_valid () -> Boolean.\n\ Return true if this symbol table and line is valid, false if not." }, + { "find_line_pc_range", salpy_find_line_pc_range, METH_NOARGS, + "find_line_pc_range () -> Tuple.\n\ +Return a tuple of start and end ranges for the symbol table's line,\n\ +or None if not found." }, {NULL} /* Sentinel */ }; diff --git a/gdb/testsuite/gdb.python/py-symtab.exp b/gdb/testsuite/gdb.python/py-symtab.exp index c52f5ef..e27c066 100644 --- a/gdb/testsuite/gdb.python/py-symtab.exp +++ b/gdb/testsuite/gdb.python/py-symtab.exp @@ -58,6 +58,14 @@ gdb_test "python print sal.symtab" "gdb/testsuite/gdb.python/py-symbol.c.*" "Tes gdb_test "python print sal.pc" "${decimal}" "Test sal.pc" gdb_test "python print sal.line" "42" "Test sal.line" gdb_test "python print sal.is_valid()" "True" "Test sal.is_valid" +gdb_test "python print sal.pc == sal.find_line_pc_range()\[0\]" "True" "Test sal.find_line_pc_range() 1" +gdb_test "python print sal.find_line_pc_range()\[1\]" "${decimal}" "Test sal.find_line_pc_range() 2" + +# Test sal find_line_pc_range errors. +gdb_test "python bad_line_sal = gdb.decode_line(\"py-symbol.c:404\")\[1\]\[0\]" "" \ +"test decode_line py-symbol.c:404" +gdb_test "python print bad_line_sal.find_line_pc_range() == None" "True" \ +"find_line_pc_range for non-existent line" # Test symbol table. gdb_test "python print symtab.filename" "testsuite/gdb.python/py-symbol.c.*" "Test symtab.filename"