Home | History | Annotate | Line # | Download | only in python
py-objfile.c revision 1.10
      1 /* Python interface to objfiles.
      2 
      3    Copyright (C) 2008-2023 Free Software Foundation, Inc.
      4 
      5    This file is part of GDB.
      6 
      7    This program is free software; you can redistribute it and/or modify
      8    it under the terms of the GNU General Public License as published by
      9    the Free Software Foundation; either version 3 of the License, or
     10    (at your option) any later version.
     11 
     12    This program is distributed in the hope that it will be useful,
     13    but WITHOUT ANY WARRANTY; without even the implied warranty of
     14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15    GNU General Public License for more details.
     16 
     17    You should have received a copy of the GNU General Public License
     18    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
     19 
     20 #include "defs.h"
     21 #include "python-internal.h"
     22 #include "charset.h"
     23 #include "objfiles.h"
     24 #include "language.h"
     25 #include "build-id.h"
     26 #include "symtab.h"
     27 #include "python.h"
     28 
     29 struct objfile_object
     30 {
     31   PyObject_HEAD
     32 
     33   /* The corresponding objfile.  */
     34   struct objfile *objfile;
     35 
     36   /* Dictionary holding user-added attributes.
     37      This is the __dict__ attribute of the object.  */
     38   PyObject *dict;
     39 
     40   /* The pretty-printer list of functions.  */
     41   PyObject *printers;
     42 
     43   /* The frame filter list of functions.  */
     44   PyObject *frame_filters;
     45 
     46   /* The list of frame unwinders.  */
     47   PyObject *frame_unwinders;
     48 
     49   /* The type-printer list.  */
     50   PyObject *type_printers;
     51 
     52   /* The debug method matcher list.  */
     53   PyObject *xmethods;
     54 };
     55 
     56 extern PyTypeObject objfile_object_type
     57     CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("objfile_object");
     58 
     59 /* Clear the OBJFILE pointer in an Objfile object and remove the
     60    reference.  */
     61 struct objfpy_deleter
     62 {
     63   void operator() (objfile_object *obj)
     64   {
     65     gdbpy_enter enter_py;
     66     gdbpy_ref<objfile_object> object (obj);
     67     object->objfile = nullptr;
     68   }
     69 };
     70 
     71 static const registry<objfile>::key<objfile_object, objfpy_deleter>
     72      objfpy_objfile_data_key;
     73 
     74 /* Require that OBJF be a valid objfile.  */
     75 #define OBJFPY_REQUIRE_VALID(obj)				\
     76   do {								\
     77     if (!(obj)->objfile)					\
     78       {								\
     79 	PyErr_SetString (PyExc_RuntimeError,			\
     80 			 _("Objfile no longer exists."));	\
     81 	return NULL;						\
     82       }								\
     83   } while (0)
     84 
     85 
     86 
     88 /* An Objfile method which returns the objfile's file name, or None.  */
     89 
     90 static PyObject *
     91 objfpy_get_filename (PyObject *self, void *closure)
     92 {
     93   objfile_object *obj = (objfile_object *) self;
     94 
     95   if (obj->objfile)
     96     return (host_string_to_python_string (objfile_name (obj->objfile))
     97 	    .release ());
     98   Py_RETURN_NONE;
     99 }
    100 
    101 /* An Objfile method which returns the objfile's file name, as specified
    102    by the user, or None.  */
    103 
    104 static PyObject *
    105 objfpy_get_username (PyObject *self, void *closure)
    106 {
    107   objfile_object *obj = (objfile_object *) self;
    108 
    109   if (obj->objfile)
    110     {
    111       const char *username = obj->objfile->original_name;
    112 
    113       return host_string_to_python_string (username).release ();
    114     }
    115 
    116   Py_RETURN_NONE;
    117 }
    118 
    119 /* Get the 'is_file' attribute.  */
    120 
    121 static PyObject *
    122 objfpy_get_is_file (PyObject *o, void *ignore)
    123 {
    124   objfile_object *self = (objfile_object *) o;
    125 
    126   if (self->objfile != nullptr)
    127     return PyBool_FromLong ((self->objfile->flags & OBJF_NOT_FILENAME) == 0);
    128   Py_RETURN_NONE;
    129 }
    130 
    131 /* If SELF is a separate debug-info file, return the "backlink" field.
    132    Otherwise return None.  */
    133 
    134 static PyObject *
    135 objfpy_get_owner (PyObject *self, void *closure)
    136 {
    137   objfile_object *obj = (objfile_object *) self;
    138   struct objfile *objfile = obj->objfile;
    139   struct objfile *owner;
    140 
    141   OBJFPY_REQUIRE_VALID (obj);
    142 
    143   owner = objfile->separate_debug_objfile_backlink;
    144   if (owner != NULL)
    145     return objfile_to_objfile_object (owner).release ();
    146   Py_RETURN_NONE;
    147 }
    148 
    149 /* An Objfile method which returns the objfile's build id, or None.  */
    150 
    151 static PyObject *
    152 objfpy_get_build_id (PyObject *self, void *closure)
    153 {
    154   objfile_object *obj = (objfile_object *) self;
    155   struct objfile *objfile = obj->objfile;
    156   const struct bfd_build_id *build_id = NULL;
    157 
    158   OBJFPY_REQUIRE_VALID (obj);
    159 
    160   try
    161     {
    162       build_id = build_id_bfd_get (objfile->obfd.get ());
    163     }
    164   catch (const gdb_exception &except)
    165     {
    166       GDB_PY_HANDLE_EXCEPTION (except);
    167     }
    168 
    169   if (build_id != NULL)
    170     {
    171       std::string hex_form = bin2hex (build_id->data, build_id->size);
    172 
    173       return host_string_to_python_string (hex_form.c_str ()).release ();
    174     }
    175 
    176   Py_RETURN_NONE;
    177 }
    178 
    179 /* An Objfile method which returns the objfile's progspace, or None.  */
    180 
    181 static PyObject *
    182 objfpy_get_progspace (PyObject *self, void *closure)
    183 {
    184   objfile_object *obj = (objfile_object *) self;
    185 
    186   if (obj->objfile)
    187     return pspace_to_pspace_object (obj->objfile->pspace).release ();
    188 
    189   Py_RETURN_NONE;
    190 }
    191 
    192 static void
    193 objfpy_dealloc (PyObject *o)
    194 {
    195   objfile_object *self = (objfile_object *) o;
    196 
    197   Py_XDECREF (self->dict);
    198   Py_XDECREF (self->printers);
    199   Py_XDECREF (self->frame_filters);
    200   Py_XDECREF (self->frame_unwinders);
    201   Py_XDECREF (self->type_printers);
    202   Py_XDECREF (self->xmethods);
    203   Py_TYPE (self)->tp_free (self);
    204 }
    205 
    206 /* Initialize an objfile_object.
    207    The result is a boolean indicating success.  */
    208 
    209 static int
    210 objfpy_initialize (objfile_object *self)
    211 {
    212   self->objfile = NULL;
    213 
    214   self->dict = PyDict_New ();
    215   if (self->dict == NULL)
    216     return 0;
    217 
    218   self->printers = PyList_New (0);
    219   if (self->printers == NULL)
    220     return 0;
    221 
    222   self->frame_filters = PyDict_New ();
    223   if (self->frame_filters == NULL)
    224     return 0;
    225 
    226   self->frame_unwinders = PyList_New (0);
    227   if (self->frame_unwinders == NULL)
    228     return 0;
    229 
    230   self->type_printers = PyList_New (0);
    231   if (self->type_printers == NULL)
    232     return 0;
    233 
    234   self->xmethods = PyList_New (0);
    235   if (self->xmethods == NULL)
    236     return 0;
    237 
    238   return 1;
    239 }
    240 
    241 static PyObject *
    242 objfpy_new (PyTypeObject *type, PyObject *args, PyObject *keywords)
    243 {
    244   gdbpy_ref<objfile_object> self ((objfile_object *) type->tp_alloc (type, 0));
    245 
    246   if (self != NULL)
    247     {
    248       if (!objfpy_initialize (self.get ()))
    249 	return NULL;
    250     }
    251 
    252   return (PyObject *) self.release ();
    253 }
    254 
    255 PyObject *
    256 objfpy_get_printers (PyObject *o, void *ignore)
    257 {
    258   objfile_object *self = (objfile_object *) o;
    259 
    260   Py_INCREF (self->printers);
    261   return self->printers;
    262 }
    263 
    264 static int
    265 objfpy_set_printers (PyObject *o, PyObject *value, void *ignore)
    266 {
    267   objfile_object *self = (objfile_object *) o;
    268 
    269   if (! value)
    270     {
    271       PyErr_SetString (PyExc_TypeError,
    272 		       _("Cannot delete the pretty_printers attribute."));
    273       return -1;
    274     }
    275 
    276   if (! PyList_Check (value))
    277     {
    278       PyErr_SetString (PyExc_TypeError,
    279 		       _("The pretty_printers attribute must be a list."));
    280       return -1;
    281     }
    282 
    283   /* Take care in case the LHS and RHS are related somehow.  */
    284   gdbpy_ref<> tmp (self->printers);
    285   Py_INCREF (value);
    286   self->printers = value;
    287 
    288   return 0;
    289 }
    290 
    291 /* Return the Python dictionary attribute containing frame filters for
    292    this object file.  */
    293 PyObject *
    294 objfpy_get_frame_filters (PyObject *o, void *ignore)
    295 {
    296   objfile_object *self = (objfile_object *) o;
    297 
    298   Py_INCREF (self->frame_filters);
    299   return self->frame_filters;
    300 }
    301 
    302 /* Set this object file's frame filters dictionary to FILTERS.  */
    303 static int
    304 objfpy_set_frame_filters (PyObject *o, PyObject *filters, void *ignore)
    305 {
    306   objfile_object *self = (objfile_object *) o;
    307 
    308   if (! filters)
    309     {
    310       PyErr_SetString (PyExc_TypeError,
    311 		       _("Cannot delete the frame filters attribute."));
    312       return -1;
    313     }
    314 
    315   if (! PyDict_Check (filters))
    316     {
    317       PyErr_SetString (PyExc_TypeError,
    318 		       _("The frame_filters attribute must be a dictionary."));
    319       return -1;
    320     }
    321 
    322   /* Take care in case the LHS and RHS are related somehow.  */
    323   gdbpy_ref<> tmp (self->frame_filters);
    324   Py_INCREF (filters);
    325   self->frame_filters = filters;
    326 
    327   return 0;
    328 }
    329 
    330 /* Return the frame unwinders attribute for this object file.  */
    331 
    332 PyObject *
    333 objfpy_get_frame_unwinders (PyObject *o, void *ignore)
    334 {
    335   objfile_object *self = (objfile_object *) o;
    336 
    337   Py_INCREF (self->frame_unwinders);
    338   return self->frame_unwinders;
    339 }
    340 
    341 /* Set this object file's frame unwinders list to UNWINDERS.  */
    342 
    343 static int
    344 objfpy_set_frame_unwinders (PyObject *o, PyObject *unwinders, void *ignore)
    345 {
    346   objfile_object *self = (objfile_object *) o;
    347 
    348   if (!unwinders)
    349     {
    350       PyErr_SetString (PyExc_TypeError,
    351 		       _("Cannot delete the frame unwinders attribute."));
    352       return -1;
    353     }
    354 
    355   if (!PyList_Check (unwinders))
    356     {
    357       PyErr_SetString (PyExc_TypeError,
    358 		       _("The frame_unwinders attribute must be a list."));
    359       return -1;
    360     }
    361 
    362   /* Take care in case the LHS and RHS are related somehow.  */
    363   gdbpy_ref<> tmp (self->frame_unwinders);
    364   Py_INCREF (unwinders);
    365   self->frame_unwinders = unwinders;
    366 
    367   return 0;
    368 }
    369 
    370 /* Get the 'type_printers' attribute.  */
    371 
    372 static PyObject *
    373 objfpy_get_type_printers (PyObject *o, void *ignore)
    374 {
    375   objfile_object *self = (objfile_object *) o;
    376 
    377   Py_INCREF (self->type_printers);
    378   return self->type_printers;
    379 }
    380 
    381 /* Get the 'xmethods' attribute.  */
    382 
    383 PyObject *
    384 objfpy_get_xmethods (PyObject *o, void *ignore)
    385 {
    386   objfile_object *self = (objfile_object *) o;
    387 
    388   Py_INCREF (self->xmethods);
    389   return self->xmethods;
    390 }
    391 
    392 /* Set the 'type_printers' attribute.  */
    393 
    394 static int
    395 objfpy_set_type_printers (PyObject *o, PyObject *value, void *ignore)
    396 {
    397   objfile_object *self = (objfile_object *) o;
    398 
    399   if (! value)
    400     {
    401       PyErr_SetString (PyExc_TypeError,
    402 		       _("Cannot delete the type_printers attribute."));
    403       return -1;
    404     }
    405 
    406   if (! PyList_Check (value))
    407     {
    408       PyErr_SetString (PyExc_TypeError,
    409 		       _("The type_printers attribute must be a list."));
    410       return -1;
    411     }
    412 
    413   /* Take care in case the LHS and RHS are related somehow.  */
    414   gdbpy_ref<> tmp (self->type_printers);
    415   Py_INCREF (value);
    416   self->type_printers = value;
    417 
    418   return 0;
    419 }
    420 
    421 /* Implementation of gdb.Objfile.is_valid (self) -> Boolean.
    422    Returns True if this object file still exists in GDB.  */
    423 
    424 static PyObject *
    425 objfpy_is_valid (PyObject *self, PyObject *args)
    426 {
    427   objfile_object *obj = (objfile_object *) self;
    428 
    429   if (! obj->objfile)
    430     Py_RETURN_FALSE;
    431 
    432   Py_RETURN_TRUE;
    433 }
    434 
    435 /* Implementation of gdb.Objfile.add_separate_debug_file (self, string). */
    436 
    437 static PyObject *
    438 objfpy_add_separate_debug_file (PyObject *self, PyObject *args, PyObject *kw)
    439 {
    440   static const char *keywords[] = { "file_name", NULL };
    441   objfile_object *obj = (objfile_object *) self;
    442   const char *file_name;
    443 
    444   OBJFPY_REQUIRE_VALID (obj);
    445 
    446   if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "s", keywords, &file_name))
    447     return NULL;
    448 
    449   try
    450     {
    451       gdb_bfd_ref_ptr abfd (symfile_bfd_open (file_name));
    452 
    453       symbol_file_add_separate (abfd, file_name, 0, obj->objfile);
    454     }
    455   catch (const gdb_exception &except)
    456     {
    457       GDB_PY_HANDLE_EXCEPTION (except);
    458     }
    459 
    460   Py_RETURN_NONE;
    461 }
    462 
    463 /* Implementation of
    464   gdb.Objfile.lookup_global_symbol (self, string [, domain]) -> gdb.Symbol.  */
    465 
    466 static PyObject *
    467 objfpy_lookup_global_symbol (PyObject *self, PyObject *args, PyObject *kw)
    468 {
    469   static const char *keywords[] = { "name", "domain", NULL };
    470   objfile_object *obj = (objfile_object *) self;
    471   const char *symbol_name;
    472   int domain = VAR_DOMAIN;
    473 
    474   OBJFPY_REQUIRE_VALID (obj);
    475 
    476   if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "s|i", keywords, &symbol_name,
    477 					&domain))
    478     return nullptr;
    479 
    480   try
    481     {
    482       struct symbol *sym = lookup_global_symbol_from_objfile
    483 	(obj->objfile, GLOBAL_BLOCK, symbol_name, (domain_enum) domain).symbol;
    484       if (sym == nullptr)
    485 	Py_RETURN_NONE;
    486 
    487       return symbol_to_symbol_object (sym);
    488     }
    489   catch (const gdb_exception &except)
    490     {
    491       GDB_PY_HANDLE_EXCEPTION (except);
    492     }
    493 
    494   Py_RETURN_NONE;
    495 }
    496 
    497 /* Implementation of
    498   gdb.Objfile.lookup_static_symbol (self, string [, domain]) -> gdb.Symbol.  */
    499 
    500 static PyObject *
    501 objfpy_lookup_static_symbol (PyObject *self, PyObject *args, PyObject *kw)
    502 {
    503   static const char *keywords[] = { "name", "domain", NULL };
    504   objfile_object *obj = (objfile_object *) self;
    505   const char *symbol_name;
    506   int domain = VAR_DOMAIN;
    507 
    508   OBJFPY_REQUIRE_VALID (obj);
    509 
    510   if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "s|i", keywords, &symbol_name,
    511 					&domain))
    512     return nullptr;
    513 
    514   try
    515     {
    516       struct symbol *sym = lookup_global_symbol_from_objfile
    517 	(obj->objfile, STATIC_BLOCK, symbol_name, (domain_enum) domain).symbol;
    518       if (sym == nullptr)
    519 	Py_RETURN_NONE;
    520 
    521       return symbol_to_symbol_object (sym);
    522     }
    523   catch (const gdb_exception &except)
    524     {
    525       GDB_PY_HANDLE_EXCEPTION (except);
    526     }
    527 
    528   Py_RETURN_NONE;
    529 }
    530 
    531 /* Implement repr() for gdb.Objfile.  */
    532 
    533 static PyObject *
    534 objfpy_repr (PyObject *self_)
    535 {
    536   objfile_object *self = (objfile_object *) self_;
    537   objfile *obj = self->objfile;
    538 
    539   if (obj == nullptr)
    540     return PyUnicode_FromString ("<gdb.Objfile (invalid)>");
    541 
    542   return PyUnicode_FromFormat ("<gdb.Objfile filename=%s>",
    543 			       objfile_name (obj));
    544 }
    545 
    546 /* Subroutine of gdbpy_lookup_objfile_by_build_id to simplify it.
    547    Return non-zero if STRING is a potentially valid build id.  */
    548 
    549 static int
    550 objfpy_build_id_ok (const char *string)
    551 {
    552   size_t i, n = strlen (string);
    553 
    554   if (n % 2 != 0)
    555     return 0;
    556   for (i = 0; i < n; ++i)
    557     {
    558       if (!isxdigit (string[i]))
    559 	return 0;
    560     }
    561   return 1;
    562 }
    563 
    564 /* Subroutine of gdbpy_lookup_objfile_by_build_id to simplify it.
    565    Returns non-zero if BUILD_ID matches STRING.
    566    It is assumed that objfpy_build_id_ok (string) returns TRUE.  */
    567 
    568 static int
    569 objfpy_build_id_matches (const struct bfd_build_id *build_id,
    570 			 const char *string)
    571 {
    572   size_t i;
    573 
    574   if (strlen (string) != 2 * build_id->size)
    575     return 0;
    576 
    577   for (i = 0; i < build_id->size; ++i)
    578     {
    579       char c1 = string[i * 2], c2 = string[i * 2 + 1];
    580       int byte = (fromhex (c1) << 4) | fromhex (c2);
    581 
    582       if (byte != build_id->data[i])
    583 	return 0;
    584     }
    585 
    586   return 1;
    587 }
    588 
    589 /* Implementation of gdb.lookup_objfile.  */
    590 
    591 PyObject *
    592 gdbpy_lookup_objfile (PyObject *self, PyObject *args, PyObject *kw)
    593 {
    594   static const char *keywords[] = { "name", "by_build_id", NULL };
    595   const char *name;
    596   PyObject *by_build_id_obj = NULL;
    597   int by_build_id;
    598 
    599   if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "s|O!", keywords,
    600 					&name, &PyBool_Type, &by_build_id_obj))
    601     return NULL;
    602 
    603   by_build_id = 0;
    604   if (by_build_id_obj != NULL)
    605     {
    606       int cmp = PyObject_IsTrue (by_build_id_obj);
    607 
    608       if (cmp < 0)
    609 	return NULL;
    610       by_build_id = cmp;
    611     }
    612 
    613   if (by_build_id && !objfpy_build_id_ok (name))
    614     {
    615       PyErr_SetString (PyExc_TypeError, _("Not a valid build id."));
    616       return NULL;
    617     }
    618 
    619   struct objfile *objfile = nullptr;
    620   if (by_build_id)
    621     gdbarch_iterate_over_objfiles_in_search_order
    622       (target_gdbarch (),
    623        [&objfile, name] (struct objfile *obj)
    624 	 {
    625 	   /* Don't return separate debug files.  */
    626 	   if (obj->separate_debug_objfile_backlink != nullptr)
    627 	     return 0;
    628 
    629 	   bfd *obfd = obj->obfd.get ();
    630 	   if (obfd == nullptr)
    631 	     return 0;
    632 
    633 	   const bfd_build_id *obfd_build_id = build_id_bfd_get (obfd);
    634 	   if (obfd_build_id == nullptr)
    635 	     return 0;
    636 
    637 	   if (!objfpy_build_id_matches (obfd_build_id, name))
    638 	     return 0;
    639 
    640 	   objfile = obj;
    641 	   return 1;
    642 	 }, gdbpy_current_objfile);
    643   else
    644     gdbarch_iterate_over_objfiles_in_search_order
    645       (target_gdbarch (),
    646        [&objfile, name] (struct objfile *obj)
    647 	 {
    648 	   /* Don't return separate debug files.  */
    649 	   if (obj->separate_debug_objfile_backlink != nullptr)
    650 	     return 0;
    651 
    652 	   if ((obj->flags & OBJF_NOT_FILENAME) != 0)
    653 	     return 0;
    654 
    655 	   const char *filename = objfile_filename (obj);
    656 	   if (filename != NULL
    657 	       && compare_filenames_for_search (filename, name))
    658 	     {
    659 	       objfile = obj;
    660 	       return 1;
    661 	     }
    662 
    663 	   if (compare_filenames_for_search (obj->original_name, name))
    664 	     {
    665 	       objfile = obj;
    666 	       return 1;
    667 	     }
    668 
    669 	   return 0;
    670 	 }, gdbpy_current_objfile);
    671 
    672   if (objfile != NULL)
    673     return objfile_to_objfile_object (objfile).release ();
    674 
    675   PyErr_SetString (PyExc_ValueError, _("Objfile not found."));
    676   return NULL;
    677 }
    678 
    679 
    680 
    682 /* Return a new reference to the Python object of type Objfile
    683    representing OBJFILE.  If the object has already been created,
    684    return it.  Otherwise, create it.  Return NULL and set the Python
    685    error on failure.  */
    686 
    687 gdbpy_ref<>
    688 objfile_to_objfile_object (struct objfile *objfile)
    689 {
    690   PyObject *result
    691     = (PyObject *) objfpy_objfile_data_key.get (objfile);
    692   if (result == NULL)
    693     {
    694       gdbpy_ref<objfile_object> object
    695 	((objfile_object *) PyObject_New (objfile_object, &objfile_object_type));
    696       if (object == NULL)
    697 	return NULL;
    698       if (!objfpy_initialize (object.get ()))
    699 	return NULL;
    700 
    701       object->objfile = objfile;
    702       objfpy_objfile_data_key.set (objfile, object.get ());
    703       result = (PyObject *) object.release ();
    704     }
    705 
    706   return gdbpy_ref<>::new_reference (result);
    707 }
    708 
    709 int
    710 gdbpy_initialize_objfile (void)
    711 {
    712   if (PyType_Ready (&objfile_object_type) < 0)
    713     return -1;
    714 
    715   return gdb_pymodule_addobject (gdb_module, "Objfile",
    716 				 (PyObject *) &objfile_object_type);
    717 }
    718 
    719 
    720 
    722 static PyMethodDef objfile_object_methods[] =
    723 {
    724   { "is_valid", objfpy_is_valid, METH_NOARGS,
    725     "is_valid () -> Boolean.\n\
    726 Return true if this object file is valid, false if not." },
    727 
    728   { "add_separate_debug_file", (PyCFunction) objfpy_add_separate_debug_file,
    729     METH_VARARGS | METH_KEYWORDS,
    730     "add_separate_debug_file (file_name).\n\
    731 Add FILE_NAME to the list of files containing debug info for the objfile." },
    732 
    733   { "lookup_global_symbol", (PyCFunction) objfpy_lookup_global_symbol,
    734     METH_VARARGS | METH_KEYWORDS,
    735     "lookup_global_symbol (name [, domain]).\n\
    736 Look up a global symbol in this objfile and return it." },
    737 
    738   { "lookup_static_symbol", (PyCFunction) objfpy_lookup_static_symbol,
    739     METH_VARARGS | METH_KEYWORDS,
    740     "lookup_static_symbol (name [, domain]).\n\
    741 Look up a static-linkage global symbol in this objfile and return it." },
    742 
    743   { NULL }
    744 };
    745 
    746 static gdb_PyGetSetDef objfile_getset[] =
    747 {
    748   { "__dict__", gdb_py_generic_dict, NULL,
    749     "The __dict__ for this objfile.", &objfile_object_type },
    750   { "filename", objfpy_get_filename, NULL,
    751     "The objfile's filename, or None.", NULL },
    752   { "username", objfpy_get_username, NULL,
    753     "The name of the objfile as provided by the user, or None.", NULL },
    754   { "owner", objfpy_get_owner, NULL,
    755     "The objfile owner of separate debug info objfiles, or None.",
    756     NULL },
    757   { "build_id", objfpy_get_build_id, NULL,
    758     "The objfile's build id, or None.", NULL },
    759   { "progspace", objfpy_get_progspace, NULL,
    760     "The objfile's progspace, or None.", NULL },
    761   { "pretty_printers", objfpy_get_printers, objfpy_set_printers,
    762     "Pretty printers.", NULL },
    763   { "frame_filters", objfpy_get_frame_filters,
    764     objfpy_set_frame_filters, "Frame Filters.", NULL },
    765   { "frame_unwinders", objfpy_get_frame_unwinders,
    766     objfpy_set_frame_unwinders, "Frame Unwinders", NULL },
    767   { "type_printers", objfpy_get_type_printers, objfpy_set_type_printers,
    768     "Type printers.", NULL },
    769   { "xmethods", objfpy_get_xmethods, NULL,
    770     "Debug methods.", NULL },
    771   { "is_file", objfpy_get_is_file, nullptr,
    772     "Whether this objfile came from a file.", nullptr },
    773   { NULL }
    774 };
    775 
    776 PyTypeObject objfile_object_type =
    777 {
    778   PyVarObject_HEAD_INIT (NULL, 0)
    779   "gdb.Objfile",		  /*tp_name*/
    780   sizeof (objfile_object),	  /*tp_basicsize*/
    781   0,				  /*tp_itemsize*/
    782   objfpy_dealloc,		  /*tp_dealloc*/
    783   0,				  /*tp_print*/
    784   0,				  /*tp_getattr*/
    785   0,				  /*tp_setattr*/
    786   0,				  /*tp_compare*/
    787   objfpy_repr,			  /*tp_repr*/
    788   0,				  /*tp_as_number*/
    789   0,				  /*tp_as_sequence*/
    790   0,				  /*tp_as_mapping*/
    791   0,				  /*tp_hash */
    792   0,				  /*tp_call*/
    793   0,				  /*tp_str*/
    794   0,				  /*tp_getattro*/
    795   0,				  /*tp_setattro*/
    796   0,				  /*tp_as_buffer*/
    797   Py_TPFLAGS_DEFAULT,		  /*tp_flags*/
    798   "GDB objfile object",		  /* tp_doc */
    799   0,				  /* tp_traverse */
    800   0,				  /* tp_clear */
    801   0,				  /* tp_richcompare */
    802   0,				  /* tp_weaklistoffset */
    803   0,				  /* tp_iter */
    804   0,				  /* tp_iternext */
    805   objfile_object_methods,	  /* tp_methods */
    806   0,				  /* tp_members */
    807   objfile_getset,		  /* tp_getset */
    808   0,				  /* tp_base */
    809   0,				  /* tp_dict */
    810   0,				  /* tp_descr_get */
    811   0,				  /* tp_descr_set */
    812   offsetof (objfile_object, dict), /* tp_dictoffset */
    813   0,				  /* tp_init */
    814   0,				  /* tp_alloc */
    815   objfpy_new,			  /* tp_new */
    816 };
    817