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