From: Jan Vrany Date: Wed, 19 Mar 2025 21:12:53 +0000 (+0000) Subject: gdb/python: preserve identity for gdb.Symbol objects X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=d518cb9be11af64951af8eb6f998751097f58a1c;p=thirdparty%2Fbinutils-gdb.git gdb/python: preserve identity for gdb.Symbol objects This commit changes symbol_to_symbol_object() so that each it is called with a particular struct symbol * it returns the very same gdb.Symbol object. This is done in the same way as for gdb.Symtab objects in earlier commit ("gdb/python: preserve identity for gdb.Symtab objects") except that symbols may be either objfile-owned or arch-owned. Prior this commit, arch-owned objects we not put into any list (like objfile-owned ones) so they could not be easily looked up. This commit changes the code so arch-owned list are put into per-architecture list which is then used (solely) for looking up arch-owned gdb.Symbol. Approved-By: Tom Tromey --- diff --git a/gdb/python/py-symbol.c b/gdb/python/py-symbol.c index 3ce104984b4..d6baf8d7ae5 100644 --- a/gdb/python/py-symbol.c +++ b/gdb/python/py-symbol.c @@ -70,6 +70,8 @@ struct symbol_object_deleter static const registry::key sympy_objfile_data_key; +static const registry::key + sympy_gdbarch_data_key; static PyObject * sympy_str (PyObject *self) @@ -347,19 +349,29 @@ static void set_symbol (symbol_object *obj, struct symbol *symbol) { obj->symbol = symbol; - obj->prev = NULL; - if (symbol->is_objfile_owned () - && symbol->symtab () != NULL) + obj->prev = nullptr; + if (symbol->is_objfile_owned ()) { - struct objfile *objfile = symbol->objfile (); + /* Can it really happen that symbol->symtab () is NULL? */ + if (symbol->symtab () != nullptr) + { + struct objfile *objfile = symbol->objfile (); - obj->next = sympy_objfile_data_key.get (objfile); + obj->next = sympy_objfile_data_key.get (objfile); + if (obj->next) + obj->next->prev = obj; + sympy_objfile_data_key.set (objfile, obj); + } + } + else + { + struct gdbarch *arch = symbol->arch (); + + obj->next = sympy_gdbarch_data_key.get (arch); if (obj->next) obj->next->prev = obj; - sympy_objfile_data_key.set (objfile, obj); + sympy_gdbarch_data_key.set (arch, obj); } - else - obj->next = NULL; } /* Create a new symbol object (gdb.Symbol) that encapsulates the struct @@ -369,6 +381,23 @@ symbol_to_symbol_object (struct symbol *sym) { symbol_object *sym_obj; + /* Look if there's already a gdb.Symtab object for given SYMTAB + and if so, return it. */ + if (sym->is_objfile_owned ()) + sym_obj = sympy_objfile_data_key.get (sym->objfile ()); + else + sym_obj = sympy_gdbarch_data_key.get (sym->arch ()); + + while (sym_obj != nullptr) + { + if (sym_obj->symbol == sym) + { + Py_INCREF (sym_obj); + return (PyObject*)sym_obj; + } + sym_obj = sym_obj->next; + } + sym_obj = PyObject_New (symbol_object, &symbol_object_type); if (sym_obj) set_symbol (sym_obj, sym); @@ -392,10 +421,19 @@ sympy_dealloc (PyObject *obj) if (sym_obj->prev) sym_obj->prev->next = sym_obj->next; - else if (sym_obj->symbol != NULL - && sym_obj->symbol->is_objfile_owned () - && sym_obj->symbol->symtab () != NULL) - sympy_objfile_data_key.set (sym_obj->symbol->objfile (), sym_obj->next); + else if (sym_obj->symbol != nullptr) + { + if (sym_obj->symbol->is_objfile_owned ()) + { + /* Can it really happen that symbol->symtab () is NULL? */ + if (sym_obj->symbol->symtab () != nullptr) + sympy_objfile_data_key.set (sym_obj->symbol->objfile (), + sym_obj->next); + } + else + sympy_gdbarch_data_key.set (sym_obj->symbol->arch (), + sym_obj->next); + } if (sym_obj->next) sym_obj->next->prev = sym_obj->prev; sym_obj->symbol = NULL;