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