New "owner" attribute for gdb.Objfile.
[external/binutils.git] / gdb / python / py-objfile.c
1 /* Python interface to objfiles.
2
3    Copyright (C) 2008-2014 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
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   /* The type-printer list.  */
45   PyObject *type_printers;
46
47   /* The debug method matcher list.  */
48   PyObject *xmethods;
49 } objfile_object;
50
51 static PyTypeObject objfile_object_type
52     CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("objfile_object");
53
54 static const struct objfile_data *objfpy_objfile_data_key;
55
56 /* Require that OBJF be a valid objfile.  */
57 #define OBJFPY_REQUIRE_VALID(obj)                               \
58   do {                                                          \
59     if (!(obj)->objfile)                                        \
60       {                                                         \
61         PyErr_SetString (PyExc_RuntimeError,                    \
62                          _("Objfile no longer exists."));       \
63         return NULL;                                            \
64       }                                                         \
65   } while (0)
66
67 \f
68
69 /* An Objfile method which returns the objfile's file name, or None.  */
70
71 static PyObject *
72 objfpy_get_filename (PyObject *self, void *closure)
73 {
74   objfile_object *obj = (objfile_object *) self;
75
76   if (obj->objfile)
77     return PyString_Decode (objfile_name (obj->objfile),
78                             strlen (objfile_name (obj->objfile)),
79                             host_charset (), NULL);
80   Py_RETURN_NONE;
81 }
82
83 /* If SELF is a separate debug-info file, return the "backlink" field.
84    Otherwise return None.  */
85
86 static PyObject *
87 objfpy_get_owner (PyObject *self, void *closure)
88 {
89   objfile_object *obj = (objfile_object *) self;
90   struct objfile *objfile = obj->objfile;
91   struct objfile *owner;
92
93   OBJFPY_REQUIRE_VALID (obj);
94
95   owner = objfile->separate_debug_objfile_backlink;
96
97   if (owner != NULL)
98     return objfile_to_objfile_object (owner);
99   Py_RETURN_NONE;
100 }
101
102 /* An Objfile method which returns the objfile's build id, or None.  */
103
104 static PyObject *
105 objfpy_get_build_id (PyObject *self, void *closure)
106 {
107   objfile_object *obj = (objfile_object *) self;
108   struct objfile *objfile = obj->objfile;
109   const struct elf_build_id *build_id = NULL;
110   volatile struct gdb_exception except;
111
112   OBJFPY_REQUIRE_VALID (obj);
113
114   TRY_CATCH (except, RETURN_MASK_ALL)
115     {
116       build_id = build_id_bfd_get (objfile->obfd);
117     }
118   GDB_PY_HANDLE_EXCEPTION (except);
119
120   if (build_id != NULL)
121     {
122       char *hex_form = make_hex_string (build_id->data, build_id->size);
123       PyObject *result;
124
125       result = PyString_Decode (hex_form, strlen (hex_form),
126                                 host_charset (), NULL);
127       xfree (hex_form);
128       return result;
129     }
130
131   Py_RETURN_NONE;
132 }
133
134 /* An Objfile method which returns the objfile's progspace, or None.  */
135
136 static PyObject *
137 objfpy_get_progspace (PyObject *self, void *closure)
138 {
139   objfile_object *obj = (objfile_object *) self;
140
141   if (obj->objfile)
142     {
143       PyObject *pspace =  pspace_to_pspace_object (obj->objfile->pspace);
144
145       Py_XINCREF (pspace);
146       return pspace;
147     }
148
149   Py_RETURN_NONE;
150 }
151
152 static void
153 objfpy_dealloc (PyObject *o)
154 {
155   objfile_object *self = (objfile_object *) o;
156
157   Py_XDECREF (self->dict);
158   Py_XDECREF (self->printers);
159   Py_XDECREF (self->frame_filters);
160   Py_XDECREF (self->type_printers);
161   Py_XDECREF (self->xmethods);
162   Py_TYPE (self)->tp_free (self);
163 }
164
165 /* Initialize an objfile_object.
166    The result is a boolean indicating success.  */
167
168 static int
169 objfpy_initialize (objfile_object *self)
170 {
171   self->objfile = NULL;
172   self->dict = NULL;
173
174   self->printers = PyList_New (0);
175   if (self->printers == NULL)
176     return 0;
177
178   self->frame_filters = PyDict_New ();
179   if (self->frame_filters == NULL)
180     return 0;
181
182   self->type_printers = PyList_New (0);
183   if (self->type_printers == NULL)
184     return 0;
185
186   self->xmethods = PyList_New (0);
187   if (self->xmethods == NULL)
188     return 0;
189
190   return 1;
191 }
192
193 static PyObject *
194 objfpy_new (PyTypeObject *type, PyObject *args, PyObject *keywords)
195 {
196   objfile_object *self = (objfile_object *) type->tp_alloc (type, 0);
197
198   if (self)
199     {
200       if (!objfpy_initialize (self))
201         {
202           Py_DECREF (self);
203           return NULL;
204         }
205     }
206
207   return (PyObject *) self;
208 }
209
210 PyObject *
211 objfpy_get_printers (PyObject *o, void *ignore)
212 {
213   objfile_object *self = (objfile_object *) o;
214
215   Py_INCREF (self->printers);
216   return self->printers;
217 }
218
219 static int
220 objfpy_set_printers (PyObject *o, PyObject *value, void *ignore)
221 {
222   PyObject *tmp;
223   objfile_object *self = (objfile_object *) o;
224
225   if (! value)
226     {
227       PyErr_SetString (PyExc_TypeError,
228                        _("Cannot delete the pretty_printers attribute."));
229       return -1;
230     }
231
232   if (! PyList_Check (value))
233     {
234       PyErr_SetString (PyExc_TypeError,
235                        _("The pretty_printers attribute must be a list."));
236       return -1;
237     }
238
239   /* Take care in case the LHS and RHS are related somehow.  */
240   tmp = self->printers;
241   Py_INCREF (value);
242   self->printers = value;
243   Py_XDECREF (tmp);
244
245   return 0;
246 }
247
248 /* Return the Python dictionary attribute containing frame filters for
249    this object file.  */
250 PyObject *
251 objfpy_get_frame_filters (PyObject *o, void *ignore)
252 {
253   objfile_object *self = (objfile_object *) o;
254
255   Py_INCREF (self->frame_filters);
256   return self->frame_filters;
257 }
258
259 /* Set this object file's frame filters dictionary to FILTERS.  */
260 static int
261 objfpy_set_frame_filters (PyObject *o, PyObject *filters, void *ignore)
262 {
263   PyObject *tmp;
264   objfile_object *self = (objfile_object *) o;
265
266   if (! filters)
267     {
268       PyErr_SetString (PyExc_TypeError,
269                        _("Cannot delete the frame filters attribute."));
270       return -1;
271     }
272
273   if (! PyDict_Check (filters))
274     {
275       PyErr_SetString (PyExc_TypeError,
276                        _("The frame_filters attribute must be a dictionary."));
277       return -1;
278     }
279
280   /* Take care in case the LHS and RHS are related somehow.  */
281   tmp = self->frame_filters;
282   Py_INCREF (filters);
283   self->frame_filters = filters;
284   Py_XDECREF (tmp);
285
286   return 0;
287 }
288
289 /* Get the 'type_printers' attribute.  */
290
291 static PyObject *
292 objfpy_get_type_printers (PyObject *o, void *ignore)
293 {
294   objfile_object *self = (objfile_object *) o;
295
296   Py_INCREF (self->type_printers);
297   return self->type_printers;
298 }
299
300 /* Get the 'xmethods' attribute.  */
301
302 PyObject *
303 objfpy_get_xmethods (PyObject *o, void *ignore)
304 {
305   objfile_object *self = (objfile_object *) o;
306
307   Py_INCREF (self->xmethods);
308   return self->xmethods;
309 }
310
311 /* Set the 'type_printers' attribute.  */
312
313 static int
314 objfpy_set_type_printers (PyObject *o, PyObject *value, void *ignore)
315 {
316   PyObject *tmp;
317   objfile_object *self = (objfile_object *) o;
318
319   if (! value)
320     {
321       PyErr_SetString (PyExc_TypeError,
322                        _("Cannot delete the type_printers attribute."));
323       return -1;
324     }
325
326   if (! PyList_Check (value))
327     {
328       PyErr_SetString (PyExc_TypeError,
329                        _("The type_printers attribute must be a list."));
330       return -1;
331     }
332
333   /* Take care in case the LHS and RHS are related somehow.  */
334   tmp = self->type_printers;
335   Py_INCREF (value);
336   self->type_printers = value;
337   Py_XDECREF (tmp);
338
339   return 0;
340 }
341
342 /* Implementation of gdb.Objfile.is_valid (self) -> Boolean.
343    Returns True if this object file still exists in GDB.  */
344
345 static PyObject *
346 objfpy_is_valid (PyObject *self, PyObject *args)
347 {
348   objfile_object *obj = (objfile_object *) self;
349
350   if (! obj->objfile)
351     Py_RETURN_FALSE;
352
353   Py_RETURN_TRUE;
354 }
355
356 /* Implementation of gdb.Objfile.add_separate_debug_file (self) -> Boolean.  */
357
358 static PyObject *
359 objfpy_add_separate_debug_file (PyObject *self, PyObject *args, PyObject *kw)
360 {
361   static char *keywords[] = { "file_name", NULL };
362   objfile_object *obj = (objfile_object *) self;
363   const char *file_name;
364   int symfile_flags = 0;
365   volatile struct gdb_exception except;
366
367   OBJFPY_REQUIRE_VALID (obj);
368
369   if (!PyArg_ParseTupleAndKeywords (args, kw, "s", keywords, &file_name))
370     return NULL;
371
372   TRY_CATCH (except, RETURN_MASK_ALL)
373     {
374       bfd *abfd = symfile_bfd_open (file_name);
375
376       symbol_file_add_separate (abfd, file_name, symfile_flags, obj->objfile);
377     }
378   GDB_PY_HANDLE_EXCEPTION (except);
379
380   Py_RETURN_NONE;
381 }
382
383 \f
384
385 /* Clear the OBJFILE pointer in an Objfile object and remove the
386    reference.  */
387 static void
388 py_free_objfile (struct objfile *objfile, void *datum)
389 {
390   struct cleanup *cleanup;
391   objfile_object *object = datum;
392
393   cleanup = ensure_python_env (get_objfile_arch (objfile), current_language);
394   object->objfile = NULL;
395   Py_DECREF ((PyObject *) object);
396   do_cleanups (cleanup);
397 }
398
399 /* Return a borrowed reference to the Python object of type Objfile
400    representing OBJFILE.  If the object has already been created,
401    return it.  Otherwise, create it.  Return NULL and set the Python
402    error on failure.  */
403
404 PyObject *
405 objfile_to_objfile_object (struct objfile *objfile)
406 {
407   objfile_object *object;
408
409   object = objfile_data (objfile, objfpy_objfile_data_key);
410   if (!object)
411     {
412       object = PyObject_New (objfile_object, &objfile_object_type);
413       if (object)
414         {
415           if (!objfpy_initialize (object))
416             {
417               Py_DECREF (object);
418               return NULL;
419             }
420
421           object->objfile = objfile;
422           set_objfile_data (objfile, objfpy_objfile_data_key, object);
423         }
424     }
425
426   return (PyObject *) object;
427 }
428
429 int
430 gdbpy_initialize_objfile (void)
431 {
432   objfpy_objfile_data_key
433     = register_objfile_data_with_cleanup (NULL, py_free_objfile);
434
435   if (PyType_Ready (&objfile_object_type) < 0)
436     return -1;
437
438   return gdb_pymodule_addobject (gdb_module, "Objfile",
439                                  (PyObject *) &objfile_object_type);
440 }
441
442 \f
443
444 static PyMethodDef objfile_object_methods[] =
445 {
446   { "is_valid", objfpy_is_valid, METH_NOARGS,
447     "is_valid () -> Boolean.\n\
448 Return true if this object file is valid, false if not." },
449
450   { "add_separate_debug_file", (PyCFunction) objfpy_add_separate_debug_file,
451     METH_VARARGS | METH_KEYWORDS,
452     "add_separate_debug_file (file_name).\n\
453 Add FILE_NAME to the list of files containing debug info for the objfile." },
454
455   { NULL }
456 };
457
458 static PyGetSetDef objfile_getset[] =
459 {
460   { "__dict__", gdb_py_generic_dict, NULL,
461     "The __dict__ for this objfile.", &objfile_object_type },
462   { "filename", objfpy_get_filename, NULL,
463     "The objfile's filename, or None.", NULL },
464   { "owner", objfpy_get_owner, NULL,
465     "The objfile owner of separate debug info objfiles, or None.",
466     NULL },
467   { "build_id", objfpy_get_build_id, NULL,
468     "The objfile's build id, or None.", NULL },
469   { "progspace", objfpy_get_progspace, NULL,
470     "The objfile's progspace, or None.", NULL },
471   { "pretty_printers", objfpy_get_printers, objfpy_set_printers,
472     "Pretty printers.", NULL },
473   { "frame_filters", objfpy_get_frame_filters,
474     objfpy_set_frame_filters, "Frame Filters.", NULL },
475   { "type_printers", objfpy_get_type_printers, objfpy_set_type_printers,
476     "Type printers.", NULL },
477   { "xmethods", objfpy_get_xmethods, NULL,
478     "Debug methods.", NULL },
479   { NULL }
480 };
481
482 static PyTypeObject objfile_object_type =
483 {
484   PyVarObject_HEAD_INIT (NULL, 0)
485   "gdb.Objfile",                  /*tp_name*/
486   sizeof (objfile_object),        /*tp_basicsize*/
487   0,                              /*tp_itemsize*/
488   objfpy_dealloc,                 /*tp_dealloc*/
489   0,                              /*tp_print*/
490   0,                              /*tp_getattr*/
491   0,                              /*tp_setattr*/
492   0,                              /*tp_compare*/
493   0,                              /*tp_repr*/
494   0,                              /*tp_as_number*/
495   0,                              /*tp_as_sequence*/
496   0,                              /*tp_as_mapping*/
497   0,                              /*tp_hash */
498   0,                              /*tp_call*/
499   0,                              /*tp_str*/
500   0,                              /*tp_getattro*/
501   0,                              /*tp_setattro*/
502   0,                              /*tp_as_buffer*/
503   Py_TPFLAGS_DEFAULT,             /*tp_flags*/
504   "GDB objfile object",           /* tp_doc */
505   0,                              /* tp_traverse */
506   0,                              /* tp_clear */
507   0,                              /* tp_richcompare */
508   0,                              /* tp_weaklistoffset */
509   0,                              /* tp_iter */
510   0,                              /* tp_iternext */
511   objfile_object_methods,         /* tp_methods */
512   0,                              /* tp_members */
513   objfile_getset,                 /* tp_getset */
514   0,                              /* tp_base */
515   0,                              /* tp_dict */
516   0,                              /* tp_descr_get */
517   0,                              /* tp_descr_set */
518   offsetof (objfile_object, dict), /* tp_dictoffset */
519   0,                              /* tp_init */
520   0,                              /* tp_alloc */
521   objfpy_new,                     /* tp_new */
522 };