From: Jan Vrany Date: Thu, 21 Nov 2024 12:31:21 +0000 (+0000) Subject: gdb/python: allow instantiation of gdb.Symtab from Python X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=2034719b46e5311eb95422cdb10ec4c2162bfeff;p=thirdparty%2Fbinutils-gdb.git gdb/python: allow instantiation of gdb.Symtab from Python This commit adds code to allow user extension to instantiate gdb.Symtab. This is a step towards a Python support for dynamically generated code (JIT) in GDB. Reviewed-By: Eli Zaretskii --- diff --git a/gdb/doc/python.texi b/gdb/doc/python.texi index e2192f6c84a..3fb688c597e 100644 --- a/gdb/doc/python.texi +++ b/gdb/doc/python.texi @@ -6508,6 +6508,10 @@ This attribute is not writable. A @code{gdb.Symtab} object has the following methods: +@defun Symtab.__init__ (filename, compunit) +Create a new symtab for given @var{filename} in given @var{compunit}. +@end defun + @defun Symtab.is_valid () Returns @code{True} if the @code{gdb.Symtab} object is valid, @code{False} if not. A @code{gdb.Symtab} object can become invalid if diff --git a/gdb/python/py-symtab.c b/gdb/python/py-symtab.c index dcb78e0045f..9e5bae69d22 100644 --- a/gdb/python/py-symtab.c +++ b/gdb/python/py-symtab.c @@ -136,6 +136,8 @@ static const registry::key } \ } while (0) +static void set_symtab (symtab_object *obj, struct symtab *symtab); + static PyObject * stpy_str (PyObject *self) { @@ -279,6 +281,46 @@ stpy_get_linetable (PyObject *self, PyObject *args) return symtab_to_linetable_object (self); } +/* Object initializer; creates new symtab. + + Use: __init__(FILENAME, COMPUNIT). */ + +static int +stpy_init (PyObject *zelf, PyObject *args, PyObject *kw) +{ + struct symtab_object *self = (struct symtab_object*) zelf; + + if (self->symtab) + { + PyErr_Format (PyExc_RuntimeError, + _("Symtab object already initialized.")); + return -1; + } + + static const char *keywords[] = { "filename", "compunit", nullptr }; + const char *filename; + PyObject *cu_obj; + + if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "sO", keywords, + &filename, &cu_obj)) + return -1; + + + compunit_symtab *cu = compunit_object_to_compunit (cu_obj); + if (cu == nullptr) + { + PyErr_Format (PyExc_TypeError, + _("The compunit argument is not valid gdb.Compunit " + "object")); + return -1; + } + + struct symtab *symtab = allocate_symtab (cu, filename); + set_symtab (self, symtab); + + return 0; +} + static PyObject * salpy_str (PyObject *self) { @@ -523,7 +565,6 @@ symtab_object_to_symtab (PyObject *obj) static int CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION gdbpy_initialize_symtabs (void) { - symtab_object_type.tp_new = PyType_GenericNew; if (gdbpy_type_ready (&symtab_object_type) < 0) return -1; @@ -600,7 +641,15 @@ PyTypeObject symtab_object_type = { 0, /*tp_iternext */ symtab_object_methods, /*tp_methods */ 0, /*tp_members */ - symtab_object_getset /*tp_getset */ + symtab_object_getset, /*tp_getset */ + 0, /*tp_base */ + 0, /*tp_dict */ + 0, /*tp_descr_get */ + 0, /*tp_descr_set */ + 0, /*tp_dictoffset */ + stpy_init, /*tp_init */ + 0, /*tp_alloc */ + PyType_GenericNew, /*tp_new */ }; static gdb_PyGetSetDef sal_object_getset[] = { diff --git a/gdb/testsuite/gdb.python/py-symtab.exp b/gdb/testsuite/gdb.python/py-symtab.exp index a949bf1e3b7..993f651f291 100644 --- a/gdb/testsuite/gdb.python/py-symtab.exp +++ b/gdb/testsuite/gdb.python/py-symtab.exp @@ -119,6 +119,17 @@ gdb_test "python print (symtab.compunit.global_block() is symtab.global_block()) gdb_test "python print (symtab.compunit.static_block() is symtab.static_block())" \ "True" "Test symtab.compunit.static_block() is symtab.static_block()" +# Test creating new symtab in existing compunit +gdb_py_test_silent_cmd "python cu = symtab.compunit" "remember compunit" 1 +gdb_test "python print(repr( gdb.Symtab(\"some_file.txt\", cu) ))" \ + "" \ + "test creation of symtab" + +gdb_test "python print(repr( gdb.Symtab(\"some_file.txt\", (1,2,3)) ))" \ + "TypeError.*:.*" \ + "test creation of symtab passing non-compunit object" + + # Test is_valid when the objfile is unloaded. This must be the last # test as it unloads the object file in GDB. gdb_unload @@ -129,3 +140,7 @@ gdb_test "python print (symtab.is_valid())" "False" \ gdb_test_no_output "python sal = None" "test sal destructor" gdb_test_no_output "python symtab = None" "test symtab destructor" + +gdb_test "python print(repr( gdb.Symtab(\"some_file2.txt\", cu) ))" \ + "TypeError.*:.*" \ + "test creation of symtab passing invalid compunit"