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