diff options
author | Jan Vrany <jan.vrany@labware.com> | 2024-11-21 12:31:20 +0000 |
---|---|---|
committer | Jan Vrany <jan.vrany@labware.com> | 2024-11-21 13:49:11 +0000 |
commit | 840a8c0eee3cc5c3f206bddfabd979ed65577d5a (patch) | |
tree | 5c47d2d76f56cd6252ac5a4424609bebb2f103d1 | |
parent | 42373e586463c77f241192f8c8da1a5bf7f9963a (diff) | |
download | fsf-binutils-gdb-840a8c0eee3cc5c3f206bddfabd979ed65577d5a.zip fsf-binutils-gdb-840a8c0eee3cc5c3f206bddfabd979ed65577d5a.tar.gz fsf-binutils-gdb-840a8c0eee3cc5c3f206bddfabd979ed65577d5a.tar.bz2 |
gdb/python: add gdb.Compunit
This commit introduces gdb.Compunit - a representation of struct
compunit_symtab in Python.
It also adds method gdb.Objfile.compunits() to get a list of compunits
for an objfile and adds compunit attribute to gdb.Block and gdb.Symtab
to access compunit containing given block or symbol table.
Reviewed-By: Eli Zaretskii <eliz@gnu.org>
-rw-r--r-- | gdb/Makefile.in | 1 | ||||
-rw-r--r-- | gdb/NEWS | 2 | ||||
-rw-r--r-- | gdb/doc/python.texi | 69 | ||||
-rw-r--r-- | gdb/python/py-block.c | 15 | ||||
-rw-r--r-- | gdb/python/py-compunit.c | 319 | ||||
-rw-r--r-- | gdb/python/py-objfile.c | 29 | ||||
-rw-r--r-- | gdb/python/py-symtab.c | 14 | ||||
-rw-r--r-- | gdb/python/python-internal.h | 3 | ||||
-rw-r--r-- | gdb/testsuite/gdb.python/py-block.exp | 2 | ||||
-rw-r--r-- | gdb/testsuite/gdb.python/py-compunit.exp | 62 | ||||
-rw-r--r-- | gdb/testsuite/gdb.python/py-symtab.exp | 8 |
11 files changed, 524 insertions, 0 deletions
diff --git a/gdb/Makefile.in b/gdb/Makefile.in index ecb323d..88566b1 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -438,6 +438,7 @@ SUBDIR_PYTHON_SRCS = \ python/py-value.c \ python/py-varobj.c \ python/py-xmethods.c \ + python/py-compunit.c \ python/python.c SUBDIR_PYTHON_OBS = $(patsubst %.c,%.o,$(SUBDIR_PYTHON_SRCS)) @@ -94,6 +94,8 @@ ** Added gdb.Type.function. Returns a new gdb.Type representing a function returning that type. Parameter types can be specified too. + ** Added class gdb.Compunit. + * Debugger Adapter Protocol changes ** The "scopes" request will now return a scope holding global diff --git a/gdb/doc/python.texi b/gdb/doc/python.texi index 5eb2813..59d6d34 100644 --- a/gdb/doc/python.texi +++ b/gdb/doc/python.texi @@ -220,6 +220,7 @@ optional arguments while skipping others. Example: * Blocks In Python:: Accessing blocks from Python. * Symbols In Python:: Python representation of symbols. * Symbol Tables In Python:: Python representation of symbol tables. +* Compunits In Python:: Python representation of compunits. * Line Tables In Python:: Python representation of line tables. * Breakpoints In Python:: Manipulating breakpoints using Python. * Finish Breakpoints in Python:: Setting Breakpoints on function return @@ -5691,6 +5692,11 @@ Like @code{Objfile.lookup_global_symbol}, but searches for a global symbol with static linkage named @var{name} in this objfile. @end defun +@defun Objfile.compunits () +Return a sequence of all the compunits associated with this objfile. +@xref{Compunits In Python}. +@end defun + @node Frames In Python @subsubsection Accessing inferior stack frames from Python @@ -6043,6 +6049,11 @@ have a superblock that is not the static block -- for instance this happens for an inlined function. @end defvar +@defvar Block.compunit +The compunit containing this block. @xref{Compunits In Python}. +This attribute is not writable. +@end defvar + @defvar Block.superblock The block containing this block. If this parent block does not exist, this attribute holds @code{None}. This attribute is not writable. @@ -6471,6 +6482,11 @@ If no producer information is available then @code{None} is returned. This attribute is not writable. @end defvar +@defvar Symtab.compunit +The compunit this symbol table belongs to. @xref{Compunits In Python}. +This attribute is not writable. +@end defvar + A @code{gdb.Symtab} object has the following methods: @defun Symtab.is_valid () @@ -6500,6 +6516,59 @@ Return the line table associated with the symbol table. @xref{Line Tables In Python}. @end defun +@node Compunits In Python +@subsubsection Compunits representation in Python + +@cindex compunits in python +@tindex gdb.Compunit + +Access to compunits maintained by @value{GDBN} on objfiles +is exposed to Python via @code{gdb.Compunit}. Compunit for a symbol table can +be accessed via @code{compunit} property of @code{gdb.Symtab} object. +@xref{Symbol Tables In Python}. Method @code{compunits} of +@code{gdb.Objfile} can be used to get a list of all compunits belonging to +that objfile. @xref{Objfiles In Python}. + +A @code{gdb.Compunit} object has the following attributes: + +@defvar Compunit.objfile +The compunits' backing object file. @xref{Objfiles In Python}. +This attribute is not writable. +@end defvar + +@defvar Compunit.producer +The name and possibly version number of the program that +compiled the code in the compunit. +The contents of this string is up to the compiler. +If no producer information is available then @code{None} is returned. +This attribute is not writable. +@end defvar + +@defvar Compunit.symtabs +The list of symbol tables associated with this compunit. +@xref{Symbol Tables In Python}. This attribute is not writable. +@end defvar + +A @code{gdb.Compunit} object has the following methods: + +@defun Compunit.is_valid () +Returns @code{True} if the @code{gdb.Compunit} object is valid, +@code{False} if not. A @code{gdb.Compunit} object can become invalid if +the compunit it refers to does not exist in @value{GDBN} any +longer. All other @code{gdb.Compunit} methods will throw an exception +if it is invalid at the time the method is called. +@end defun + +@defun Compunit.global_block () +Return the global block of the underlying compunit. +@xref{Blocks In Python}. +@end defun + +@defun Compunit.static_block () +Return the static block of the underlying compunit. +@xref{Blocks In Python}. +@end defun + @node Line Tables In Python @subsubsection Manipulating line tables using Python diff --git a/gdb/python/py-block.c b/gdb/python/py-block.c index 1c5eab4..a05a279 100644 --- a/gdb/python/py-block.c +++ b/gdb/python/py-block.c @@ -215,6 +215,19 @@ blpy_get_static_block (PyObject *self, void *closure) return block_to_block_object (static_block, self_obj->objfile); } +/* Getter function for Block.compunit. */ + +static PyObject * +blpy_get_compunit (PyObject *self, void *closure) +{ + const struct block *block; + + BLPY_REQUIRE_VALID (self, block); + + return compunit_to_compunit_object ( + block->global_block ()->compunit ()).release (); +} + /* Implementation of gdb.Block.is_global (self) -> Boolean. Returns True if this block object is a global block. */ @@ -553,6 +566,8 @@ static gdb_PyGetSetDef block_object_getset[] = { "Block containing the global block.", NULL }, { "static_block", blpy_get_static_block, NULL, "Block containing the static block.", NULL }, + { "compunit", blpy_get_compunit, nullptr, + "Compunit containing this block.", nullptr }, { "is_static", blpy_is_static, NULL, "Whether this block is a static block.", NULL }, { "is_global", blpy_is_global, NULL, diff --git a/gdb/python/py-compunit.c b/gdb/python/py-compunit.c new file mode 100644 index 0000000..829746c --- /dev/null +++ b/gdb/python/py-compunit.c @@ -0,0 +1,319 @@ +/* Python interface to compunits. + + Copyright (C) 2008-2024 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include "charset.h" +#include "symtab.h" +#include "source.h" +#include "python-internal.h" +#include "objfiles.h" +#include "block.h" + +struct compunit_object { + PyObject_HEAD + + /* The GDB compunit structure. */ + struct compunit_symtab *compunit; + + /* A compunit object is associated with an objfile, so keep track with + a doubly-linked list, rooted in the objfile. This allows + invalidation of the underlying struct compunit_symtab when the objfile is + deleted. */ + compunit_object *prev; + compunit_object *next; +}; + +/* This function is called when an objfile is about to be freed. + Invalidate the compunit as further actions on the compunit + would result in bad data. All access to obj->compunit should be + gated by CUPY_REQUIRE_VALID which will raise an exception on + compunits. */ +struct cupy_deleter +{ + void operator() (compunit_object *obj) + { + while (obj) + { + compunit_object *next = obj->next; + + obj->compunit = nullptr; + obj->next = nullptr; + obj->prev = nullptr; + obj = next; + } + } +}; + +extern PyTypeObject compunit_object_type + CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("compunit_object"); +static const registry<objfile>::key<compunit_object, cupy_deleter> + cupy_objfile_data_key; + +/* Require a valid compunit. All access to compunit_object->compunit + should be gated by this call. */ + +#define CUPY_REQUIRE_VALID(compunit_obj, compunit) \ + do { \ + compunit = compunit_object_to_compunit (compunit_obj); \ + if (compunit == nullptr) \ + { \ + PyErr_SetString (PyExc_RuntimeError, \ + _("Compunit object is invalid.")); \ + return nullptr; \ + } \ + } while (0) + + +/* Getter function for gdb.Compunit.objfile. */ + +static PyObject * +cupy_get_objfile (PyObject *self, void *closure) +{ + struct compunit_symtab *compunit = nullptr; + + CUPY_REQUIRE_VALID (self, compunit); + + return objfile_to_objfile_object (compunit->objfile ()).release (); +} + +/* Getter function for gdb.Compunit.producer. */ + +static PyObject * +cupy_get_producer (PyObject *self, void *closure) +{ + struct compunit_symtab *compunit = nullptr; + + CUPY_REQUIRE_VALID (self, compunit); + if (compunit->producer () != nullptr) + { + const char *producer = compunit->producer (); + + return host_string_to_python_string (producer).release (); + } + + Py_RETURN_NONE; +} + +/* Implementation of gdb.Compunit.is_valid (self) -> Boolean. + Returns True if this Symbol table still exists in GDB. */ + +static PyObject * +cupy_is_valid (PyObject *self, PyObject *args) +{ + struct compunit_symtab *compunit = nullptr; + + compunit = compunit_object_to_compunit (self); + if (compunit == nullptr) + Py_RETURN_FALSE; + + Py_RETURN_TRUE; +} + +/* Return the GLOBAL_BLOCK of the underlying compunit. */ + +static PyObject * +cupy_global_block (PyObject *self, PyObject *args) +{ + struct compunit_symtab *compunit = nullptr; + const struct blockvector *blockvector; + + CUPY_REQUIRE_VALID (self, compunit); + + blockvector = compunit->blockvector (); + const struct block *block = blockvector->global_block (); + + return block_to_block_object (block, compunit->objfile ()); +} + +/* Return the STATIC_BLOCK of the underlying compunit. */ + +static PyObject * +cupy_static_block (PyObject *self, PyObject *args) +{ + struct compunit_symtab *compunit = nullptr; + const struct blockvector *blockvector; + + CUPY_REQUIRE_VALID (self, compunit); + + blockvector = compunit->blockvector (); + const struct block *block = blockvector->static_block (); + + return block_to_block_object (block, compunit->objfile ()); +} + +static PyObject * +cupy_get_symtabs (PyObject *self, void *closure) +{ + struct compunit_symtab *compunit = nullptr; + + CUPY_REQUIRE_VALID (self, compunit); + + gdbpy_ref<> list (PyList_New (0)); + if (list == nullptr) + return nullptr; + + for (struct symtab *each : compunit->filetabs ()) + { + { + gdbpy_ref<> item (symtab_to_symtab_object (each)); + if (item.get () == nullptr + || PyList_Append (list.get (), item.get ()) == -1) + return nullptr; + } + } + + return list.release (); +} + +static void +cupy_dealloc (PyObject *obj) +{ + compunit_object *compunit = (compunit_object *) obj; + + if (compunit->prev) + compunit->prev->next = compunit->next; + else if (compunit->compunit) + cupy_objfile_data_key.set (compunit->compunit->objfile (), + compunit->next); + if (compunit->next) + compunit->next->prev = compunit->prev; + compunit->compunit = nullptr; + Py_TYPE (obj)->tp_free (obj); +} + +/* Given a compunit, and a compunit_object that has previously been + allocated and initialized, populate the compunit_object with the + struct compunit_symtab data. Also, register the compunit_object life-cycle + with the life-cycle of the object file associated with this + compunit, if needed. */ +static void +set_compunit (compunit_object *obj, struct compunit_symtab *compunit) +{ + obj->compunit = compunit; + obj->prev = nullptr; + if (compunit) + { + obj->next = cupy_objfile_data_key.get (compunit->objfile ()); + if (obj->next) + obj->next->prev = obj; + cupy_objfile_data_key.set (compunit->objfile (), obj); + } + else + obj->next = nullptr; +} + +/* Return a new reference to gdb.Compunit Python object representing + COMPUNIT. Return NULL and set the Python error on failure. */ +gdbpy_ref<> +compunit_to_compunit_object (struct compunit_symtab *compunit) +{ + compunit_object *compunit_obj; + + compunit_obj = PyObject_NEW(compunit_object, &compunit_object_type); + if (compunit_obj) + set_compunit(compunit_obj, compunit); + + return gdbpy_ref<>::new_reference ((PyObject * )compunit_obj); +} + +/* Return struct compunit_symtab reference that is wrapped by this object. */ +struct compunit_symtab * +compunit_object_to_compunit (PyObject *obj) +{ + if (! PyObject_TypeCheck (obj, &compunit_object_type)) + return nullptr; + return ((compunit_object *) obj)->compunit; +} + +static int CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION +gdbpy_initialize_compunits (void) +{ + if (gdbpy_type_ready (&compunit_object_type) < 0) + return -1; + + return 0; +} + +GDBPY_INITIALIZE_FILE (gdbpy_initialize_compunits); + + + +static gdb_PyGetSetDef compunit_object_getset[] = { + { "objfile", cupy_get_objfile, nullptr, "The compunit's objfile.", + nullptr }, + { "producer", cupy_get_producer, nullptr, + "The name/version of the program that compiled this compunit.", nullptr }, + { "symtabs", cupy_get_symtabs, nullptr, + "List of symbol tables associated with this compunit", nullptr }, + {nullptr} /* Sentinel */ +}; + +static PyMethodDef compunit_object_methods[] = { + { "is_valid", cupy_is_valid, METH_NOARGS, + "is_valid () -> Boolean.\n\ +Return true if this compunit is valid, false if not." }, + { "global_block", cupy_global_block, METH_NOARGS, + "global_block () -> gdb.Block.\n\ +Return the global block of the compunit." }, + { "static_block", cupy_static_block, METH_NOARGS, + "static_block () -> gdb.Block.\n\ +Return the static block of the compunit." }, + {nullptr} /* Sentinel */ +}; + +PyTypeObject compunit_object_type = { + PyVarObject_HEAD_INIT (nullptr, 0) + "gdb.Compunit", /*tp_name*/ + sizeof (compunit_object), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + cupy_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash */ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT, /*tp_flags*/ + "GDB compunit object", /*tp_doc */ + 0, /*tp_traverse */ + 0, /*tp_clear */ + gdbpy_richcompare<compunit_object, compunit_symtab, + &compunit_object::compunit>,/*tp_richcompare */ + 0, /*tp_weaklistoffset */ + 0, /*tp_iter */ + 0, /*tp_iternext */ + compunit_object_methods, /*tp_methods */ + 0, /*tp_members */ + compunit_object_getset, /*tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + PyType_GenericNew /* tp_new */ +}; diff --git a/gdb/python/py-objfile.c b/gdb/python/py-objfile.c index 6ce58a1..e006fcc 100644 --- a/gdb/python/py-objfile.c +++ b/gdb/python/py-objfile.c @@ -544,6 +544,31 @@ objfpy_repr (PyObject *self_) objfile_name (obj)); } +/* Implementation of gdb.Objfile.compunits() -> List */ + +static PyObject * +objfpy_compunits (PyObject *self_, PyObject *args) +{ + objfile_object *self = (objfile_object *) self_; + + OBJFPY_REQUIRE_VALID (self); + + gdbpy_ref<> list (PyList_New (0)); + if (list == nullptr) + return nullptr; + + for (struct compunit_symtab *compunit : self->objfile->compunits ()) + { + gdbpy_ref<> item = compunit_to_compunit_object (compunit); + + if (item.get () == nullptr + || PyList_Append (list.get (), item.get ()) == -1) + return nullptr; + } + + return list.release (); +} + /* Subroutine of gdbpy_lookup_objfile_by_build_id to simplify it. Return non-zero if STRING is a potentially valid build id. */ @@ -737,6 +762,10 @@ Look up a global symbol in this objfile and return it." }, "lookup_static_symbol (name [, domain]).\n\ Look up a static-linkage global symbol in this objfile and return it." }, + { "compunits", objfpy_compunits, METH_NOARGS, + "compunits () -> List.\n\ +Return a sequence of compunits associated to this objfile." }, + { NULL } }; diff --git a/gdb/python/py-symtab.c b/gdb/python/py-symtab.c index 5330b15..dcb78e0 100644 --- a/gdb/python/py-symtab.c +++ b/gdb/python/py-symtab.c @@ -193,6 +193,18 @@ stpy_get_producer (PyObject *self, void *closure) Py_RETURN_NONE; } +/* Getter function for Symtab.compunit. */ + +static PyObject * +stpy_get_compunit (PyObject *self, void *closure) +{ + struct symtab *symtab = nullptr; + + STPY_REQUIRE_VALID (self, symtab); + + return compunit_to_compunit_object (symtab->compunit ()).release (); +} + static PyObject * stpy_fullname (PyObject *self, PyObject *args) { @@ -533,6 +545,8 @@ static gdb_PyGetSetDef symtab_object_getset[] = { NULL }, { "producer", stpy_get_producer, NULL, "The name/version of the program that compiled this symtab.", NULL }, + { "compunit", stpy_get_compunit, nullptr, + "The compunit this symtab belongs to.", nullptr }, {NULL} /* Sentinel */ }; diff --git a/gdb/python/python-internal.h b/gdb/python/python-internal.h index 4d4810d..0a52cb8 100644 --- a/gdb/python/python-internal.h +++ b/gdb/python/python-internal.h @@ -555,6 +555,8 @@ gdbpy_ref<thread_object> create_thread_object (struct thread_info *tp); gdbpy_ref<> thread_to_thread_object (thread_info *thr);; gdbpy_ref<inferior_object> inferior_to_inferior_object (inferior *inf); +gdbpy_ref<> compunit_to_compunit_object (struct compunit_symtab *compunit); + PyObject *gdbpy_buffer_to_membuf (gdb::unique_xmalloc_ptr<gdb_byte> buffer, CORE_ADDR address, ULONGEST length); @@ -571,6 +573,7 @@ struct symtab *symtab_object_to_symtab (PyObject *obj); struct symtab_and_line *sal_object_to_symtab_and_line (PyObject *obj); frame_info_ptr frame_object_to_frame_info (PyObject *frame_obj); struct gdbarch *arch_object_to_gdbarch (PyObject *obj); +struct compunit_symtab *compunit_object_to_compunit (PyObject *obj); extern PyObject *gdbpy_execute_mi_command (PyObject *self, PyObject *args, PyObject *kw); diff --git a/gdb/testsuite/gdb.python/py-block.exp b/gdb/testsuite/gdb.python/py-block.exp index 20f2171..64ee127 100644 --- a/gdb/testsuite/gdb.python/py-block.exp +++ b/gdb/testsuite/gdb.python/py-block.exp @@ -104,6 +104,8 @@ gdb_test "python print (repr (block))" \ "Check block in many_locals_func" gdb_test "python print (block.function)" "many_locals_func" \ "many_locals_func block" +gdb_test "python print(block.compunit)" "<gdb\.Compunit object at .*>" \ + "test compunit property" # Switch frames, then test for main block. gdb_test "up" ".*" diff --git a/gdb/testsuite/gdb.python/py-compunit.exp b/gdb/testsuite/gdb.python/py-compunit.exp new file mode 100644 index 0000000..450cd6c --- /dev/null +++ b/gdb/testsuite/gdb.python/py-compunit.exp @@ -0,0 +1,62 @@ +# Copyright (C) 2024-2024 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +# This file is part of the GDB testsuite. It tests the compunit +# support in Python. + +load_lib gdb-python.exp + +require allow_python_tests + +standard_testfile py-objfile.c + +if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile}] } { + return -1 +} + +if {![runto_main]} { + return 0 +} + +set python_error_text "Error occurred in Python.*" + +gdb_py_test_silent_cmd "python sym = gdb.lookup_symbol(\"some_var\")" \ + "Find a symbol in objfile" 1 +gdb_py_test_silent_cmd "python objfile = sym\[0\].symtab.objfile" \ + "Get backing object file" 1 + +gdb_test "python print (len(objfile.compunits()) > 0)" \ + "True" \ + "Get objfile compunits" +gdb_test "python print (objfile.compunits())" \ + "\\\[<gdb\.Compunit object at .*>\\\]" \ + "Objfile compunits return a sequence of gdb.Compunit" +gdb_test "python print (objfile.compunits()\[0\] == objfile.compunits()\[0\])" \ + "True" \ + "Compunits are comparable" +gdb_test "python print (len(objfile.compunits()\[0\].symtabs) > 0)" \ + "True" \ + "Get compunit symtabs" +gdb_test "python print (objfile.compunits()\[0\].symtabs)" \ + "\\\[<gdb\.Symtab.*>\\\]" \ + "Compunit symtabs return a sequence of gdb.Symtab" + + +gdb_unload "unload 1" + +gdb_test "python print (objfile.is_valid())" "False" \ +"Get objfile validity after unload" +gdb_test "python print (objfile.compunits())" "RuntimeError.*: Objfile no longer exists.*" \ +"Get objfile compunits after unload"
\ No newline at end of file diff --git a/gdb/testsuite/gdb.python/py-symtab.exp b/gdb/testsuite/gdb.python/py-symtab.exp index 9caa5f1..a949bf1 100644 --- a/gdb/testsuite/gdb.python/py-symtab.exp +++ b/gdb/testsuite/gdb.python/py-symtab.exp @@ -68,6 +68,8 @@ gdb_test "python print (sal.is_valid())" "True" "test sal.is_valid" gdb_test "python print (symtab.filename)" ".*${py_symbol_c}" "test symtab.filename" gdb_test "python print (symtab.objfile)" \ "<gdb.Objfile filename=.*${testfile}.*>" "test symtab.objfile" +gdb_test "python print (symtab.compunit)" \ + "<gdb.Compunit .*>" "test symtab.compunit" gdb_test "python print (symtab.fullname())" ".*${full_py_symbol_c}" "test symtab.fullname" gdb_test "python print (symtab.is_valid())" "True" "test symtab.is_valid()" gdb_test "python print (\"qq\" in global_symbols)" "True" "test qq in global symbols" @@ -110,6 +112,12 @@ gdb_test "python print (symtab != 123 )"\ "True" \ "test symtab non-equality with non-symtab" +gdb_test "python print (symtab.compunit in symtab.objfile.compunits())" \ + "True" "Test symtab.compunit in symtab.objfile.compunits()" +gdb_test "python print (symtab.compunit.global_block() is symtab.global_block())" \ + "True" "Test 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 is_valid when the objfile is unloaded. This must be the last # test as it unloads the object file in GDB. |