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