]> Git Repo - binutils.git/blob - gdb/python/py-progspace.c
update copyright year range in GDB files
[binutils.git] / gdb / python / py-progspace.c
1 /* Python interface to program spaces.
2
3    Copyright (C) 2010-2017 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 "progspace.h"
24 #include "objfiles.h"
25 #include "language.h"
26 #include "arch-utils.h"
27
28 typedef struct
29 {
30   PyObject_HEAD
31
32   /* The corresponding pspace.  */
33   struct program_space *pspace;
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 frame unwinder list.  */
46   PyObject *frame_unwinders;
47
48   /* The type-printer list.  */
49   PyObject *type_printers;
50
51   /* The debug method list.  */
52   PyObject *xmethods;
53 } pspace_object;
54
55 extern PyTypeObject pspace_object_type
56     CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("pspace_object");
57
58 static const struct program_space_data *pspy_pspace_data_key;
59
60 \f
61
62 /* An Objfile method which returns the objfile's file name, or None.  */
63
64 static PyObject *
65 pspy_get_filename (PyObject *self, void *closure)
66 {
67   pspace_object *obj = (pspace_object *) self;
68
69   if (obj->pspace)
70     {
71       struct objfile *objfile = obj->pspace->symfile_object_file;
72
73       if (objfile)
74         return host_string_to_python_string (objfile_name (objfile));
75     }
76   Py_RETURN_NONE;
77 }
78
79 static void
80 pspy_dealloc (PyObject *self)
81 {
82   pspace_object *ps_self = (pspace_object *) self;
83
84   Py_XDECREF (ps_self->dict);
85   Py_XDECREF (ps_self->printers);
86   Py_XDECREF (ps_self->frame_filters);
87   Py_XDECREF (ps_self->frame_unwinders);
88   Py_XDECREF (ps_self->type_printers);
89   Py_XDECREF (ps_self->xmethods);
90   Py_TYPE (self)->tp_free (self);
91 }
92
93 /* Initialize a pspace_object.
94    The result is a boolean indicating success.  */
95
96 static int
97 pspy_initialize (pspace_object *self)
98 {
99   self->pspace = NULL;
100
101   self->dict = PyDict_New ();
102   if (self->dict == NULL)
103     return 0;
104
105   self->printers = PyList_New (0);
106   if (self->printers == NULL)
107     return 0;
108
109   self->frame_filters = PyDict_New ();
110   if (self->frame_filters == NULL)
111     return 0;
112
113   self->frame_unwinders = PyList_New (0);
114   if (self->frame_unwinders == NULL)
115     return 0;
116
117   self->type_printers = PyList_New (0);
118   if (self->type_printers == NULL)
119     return 0;
120
121   self->xmethods = PyList_New (0);
122   if (self->xmethods == NULL)
123     return 0;
124
125   return 1;
126 }
127
128 static PyObject *
129 pspy_new (PyTypeObject *type, PyObject *args, PyObject *keywords)
130 {
131   pspace_object *self = (pspace_object *) type->tp_alloc (type, 0);
132
133   if (self)
134     {
135       if (!pspy_initialize (self))
136         {
137           Py_DECREF (self);
138           return NULL;
139         }
140     }
141
142   return (PyObject *) self;
143 }
144
145 PyObject *
146 pspy_get_printers (PyObject *o, void *ignore)
147 {
148   pspace_object *self = (pspace_object *) o;
149
150   Py_INCREF (self->printers);
151   return self->printers;
152 }
153
154 static int
155 pspy_set_printers (PyObject *o, PyObject *value, void *ignore)
156 {
157   PyObject *tmp;
158   pspace_object *self = (pspace_object *) o;
159
160   if (! value)
161     {
162       PyErr_SetString (PyExc_TypeError,
163                        "cannot delete the pretty_printers attribute");
164       return -1;
165     }
166
167   if (! PyList_Check (value))
168     {
169       PyErr_SetString (PyExc_TypeError,
170                        "the pretty_printers attribute must be a list");
171       return -1;
172     }
173
174   /* Take care in case the LHS and RHS are related somehow.  */
175   tmp = self->printers;
176   Py_INCREF (value);
177   self->printers = value;
178   Py_XDECREF (tmp);
179
180   return 0;
181 }
182
183 /* Return the Python dictionary attribute containing frame filters for
184    this program space.  */
185 PyObject *
186 pspy_get_frame_filters (PyObject *o, void *ignore)
187 {
188   pspace_object *self = (pspace_object *) o;
189
190   Py_INCREF (self->frame_filters);
191   return self->frame_filters;
192 }
193
194 /* Set this object file's frame filters dictionary to FILTERS.  */
195 static int
196 pspy_set_frame_filters (PyObject *o, PyObject *frame, void *ignore)
197 {
198   PyObject *tmp;
199   pspace_object *self = (pspace_object *) o;
200
201   if (! frame)
202     {
203       PyErr_SetString (PyExc_TypeError,
204                        "cannot delete the frame filter attribute");
205       return -1;
206     }
207
208   if (! PyDict_Check (frame))
209     {
210       PyErr_SetString (PyExc_TypeError,
211                        "the frame filter attribute must be a dictionary");
212       return -1;
213     }
214
215   /* Take care in case the LHS and RHS are related somehow.  */
216   tmp = self->frame_filters;
217   Py_INCREF (frame);
218   self->frame_filters = frame;
219   Py_XDECREF (tmp);
220
221   return 0;
222 }
223
224 /* Return the list of the frame unwinders for this program space.  */
225
226 PyObject *
227 pspy_get_frame_unwinders (PyObject *o, void *ignore)
228 {
229   pspace_object *self = (pspace_object *) o;
230
231   Py_INCREF (self->frame_unwinders);
232   return self->frame_unwinders;
233 }
234
235 /* Set this program space's list of the unwinders to UNWINDERS.  */
236
237 static int
238 pspy_set_frame_unwinders (PyObject *o, PyObject *unwinders, void *ignore)
239 {
240   PyObject *tmp;
241   pspace_object *self = (pspace_object *) o;
242
243   if (!unwinders)
244     {
245       PyErr_SetString (PyExc_TypeError,
246                        "cannot delete the frame unwinders list");
247       return -1;
248     }
249
250   if (!PyList_Check (unwinders))
251     {
252       PyErr_SetString (PyExc_TypeError,
253                        "the frame unwinders attribute must be a list");
254       return -1;
255     }
256
257   /* Take care in case the LHS and RHS are related somehow.  */
258   tmp = self->frame_unwinders;
259   Py_INCREF (unwinders);
260   self->frame_unwinders = unwinders;
261   Py_XDECREF (tmp);
262
263   return 0;
264 }
265
266 /* Get the 'type_printers' attribute.  */
267
268 static PyObject *
269 pspy_get_type_printers (PyObject *o, void *ignore)
270 {
271   pspace_object *self = (pspace_object *) o;
272
273   Py_INCREF (self->type_printers);
274   return self->type_printers;
275 }
276
277 /* Get the 'xmethods' attribute.  */
278
279 PyObject *
280 pspy_get_xmethods (PyObject *o, void *ignore)
281 {
282   pspace_object *self = (pspace_object *) o;
283
284   Py_INCREF (self->xmethods);
285   return self->xmethods;
286 }
287
288 /* Set the 'type_printers' attribute.  */
289
290 static int
291 pspy_set_type_printers (PyObject *o, PyObject *value, void *ignore)
292 {
293   PyObject *tmp;
294   pspace_object *self = (pspace_object *) o;
295
296   if (! value)
297     {
298       PyErr_SetString (PyExc_TypeError,
299                        "cannot delete the type_printers attribute");
300       return -1;
301     }
302
303   if (! PyList_Check (value))
304     {
305       PyErr_SetString (PyExc_TypeError,
306                        "the type_printers attribute must be a list");
307       return -1;
308     }
309
310   /* Take care in case the LHS and RHS are related somehow.  */
311   tmp = self->type_printers;
312   Py_INCREF (value);
313   self->type_printers = value;
314   Py_XDECREF (tmp);
315
316   return 0;
317 }
318
319 \f
320
321 /* Clear the PSPACE pointer in a Pspace object and remove the reference.  */
322
323 static void
324 py_free_pspace (struct program_space *pspace, void *datum)
325 {
326   struct cleanup *cleanup;
327   pspace_object *object = (pspace_object *) datum;
328   /* This is a fiction, but we're in a nasty spot: The pspace is in the
329      process of being deleted, we can't rely on anything in it.  Plus
330      this is one time when the current program space and current inferior
331      are not in sync: All inferiors that use PSPACE may no longer exist.
332      We don't need to do much here, and since "there is always an inferior"
333      using target_gdbarch suffices.
334      Note: We cannot call get_current_arch because it may try to access
335      the target, which may involve accessing data in the pspace currently
336      being deleted.  */
337   struct gdbarch *arch = target_gdbarch ();
338
339   cleanup = ensure_python_env (arch, current_language);
340   object->pspace = NULL;
341   Py_DECREF ((PyObject *) object);
342   do_cleanups (cleanup);
343 }
344
345 /* Return a borrowed reference to the Python object of type Pspace
346    representing PSPACE.  If the object has already been created,
347    return it.  Otherwise, create it.  Return NULL and set the Python
348    error on failure.  */
349
350 PyObject *
351 pspace_to_pspace_object (struct program_space *pspace)
352 {
353   pspace_object *object;
354
355   object = (pspace_object *) program_space_data (pspace, pspy_pspace_data_key);
356   if (!object)
357     {
358       object = PyObject_New (pspace_object, &pspace_object_type);
359       if (object)
360         {
361           if (!pspy_initialize (object))
362             {
363               Py_DECREF (object);
364               return NULL;
365             }
366
367           object->pspace = pspace;
368           set_program_space_data (pspace, pspy_pspace_data_key, object);
369         }
370     }
371
372   return (PyObject *) object;
373 }
374
375 int
376 gdbpy_initialize_pspace (void)
377 {
378   pspy_pspace_data_key
379     = register_program_space_data_with_cleanup (NULL, py_free_pspace);
380
381   if (PyType_Ready (&pspace_object_type) < 0)
382     return -1;
383
384   return gdb_pymodule_addobject (gdb_module, "Progspace",
385                                  (PyObject *) &pspace_object_type);
386 }
387
388 \f
389
390 static PyGetSetDef pspace_getset[] =
391 {
392   { "__dict__", gdb_py_generic_dict, NULL,
393     "The __dict__ for this progspace.", &pspace_object_type },
394   { "filename", pspy_get_filename, NULL,
395     "The progspace's main filename, or None.", NULL },
396   { "pretty_printers", pspy_get_printers, pspy_set_printers,
397     "Pretty printers.", NULL },
398   { "frame_filters", pspy_get_frame_filters, pspy_set_frame_filters,
399     "Frame filters.", NULL },
400   { "frame_unwinders", pspy_get_frame_unwinders, pspy_set_frame_unwinders,
401     "Frame unwinders.", NULL },
402   { "type_printers", pspy_get_type_printers, pspy_set_type_printers,
403     "Type printers.", NULL },
404   { "xmethods", pspy_get_xmethods, NULL,
405     "Debug methods.", NULL },
406   { NULL }
407 };
408
409 PyTypeObject pspace_object_type =
410 {
411   PyVarObject_HEAD_INIT (NULL, 0)
412   "gdb.Progspace",                /*tp_name*/
413   sizeof (pspace_object),         /*tp_basicsize*/
414   0,                              /*tp_itemsize*/
415   pspy_dealloc,                   /*tp_dealloc*/
416   0,                              /*tp_print*/
417   0,                              /*tp_getattr*/
418   0,                              /*tp_setattr*/
419   0,                              /*tp_compare*/
420   0,                              /*tp_repr*/
421   0,                              /*tp_as_number*/
422   0,                              /*tp_as_sequence*/
423   0,                              /*tp_as_mapping*/
424   0,                              /*tp_hash */
425   0,                              /*tp_call*/
426   0,                              /*tp_str*/
427   0,                              /*tp_getattro*/
428   0,                              /*tp_setattro*/
429   0,                              /*tp_as_buffer*/
430   Py_TPFLAGS_DEFAULT,             /*tp_flags*/
431   "GDB progspace object",         /* tp_doc */
432   0,                              /* tp_traverse */
433   0,                              /* tp_clear */
434   0,                              /* tp_richcompare */
435   0,                              /* tp_weaklistoffset */
436   0,                              /* tp_iter */
437   0,                              /* tp_iternext */
438   0,                              /* tp_methods */
439   0,                              /* tp_members */
440   pspace_getset,                  /* tp_getset */
441   0,                              /* tp_base */
442   0,                              /* tp_dict */
443   0,                              /* tp_descr_get */
444   0,                              /* tp_descr_set */
445   offsetof (pspace_object, dict), /* tp_dictoffset */
446   0,                              /* tp_init */
447   0,                              /* tp_alloc */
448   pspy_new,                       /* tp_new */
449 };
This page took 0.049142 seconds and 4 git commands to generate.