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