Add more methods to gdb.Progspace
[deliverable/binutils-gdb.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 #include "solib.h"
29 #include "block.h"
30
31 typedef struct
32 {
33 PyObject_HEAD
34
35 /* The corresponding pspace. */
36 struct program_space *pspace;
37
38 /* Dictionary holding user-added attributes.
39 This is the __dict__ attribute of the object. */
40 PyObject *dict;
41
42 /* The pretty-printer list of functions. */
43 PyObject *printers;
44
45 /* The frame filter list of functions. */
46 PyObject *frame_filters;
47
48 /* The frame unwinder list. */
49 PyObject *frame_unwinders;
50
51 /* The type-printer list. */
52 PyObject *type_printers;
53
54 /* The debug method list. */
55 PyObject *xmethods;
56 } pspace_object;
57
58 extern PyTypeObject pspace_object_type
59 CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("pspace_object");
60
61 static const struct program_space_data *pspy_pspace_data_key;
62
63 /* Require that PSPACE_OBJ be a valid program space ID. */
64 #define PSPY_REQUIRE_VALID(pspace_obj) \
65 do { \
66 if (pspace_obj->pspace == nullptr) \
67 { \
68 PyErr_SetString (PyExc_RuntimeError, \
69 _("Program space no longer exists.")); \
70 return NULL; \
71 } \
72 } while (0)
73
74 /* An Objfile method which returns the objfile's file name, or None. */
75
76 static PyObject *
77 pspy_get_filename (PyObject *self, void *closure)
78 {
79 pspace_object *obj = (pspace_object *) self;
80
81 if (obj->pspace)
82 {
83 struct objfile *objfile = obj->pspace->symfile_object_file;
84
85 if (objfile)
86 return host_string_to_python_string (objfile_name (objfile));
87 }
88 Py_RETURN_NONE;
89 }
90
91 static void
92 pspy_dealloc (PyObject *self)
93 {
94 pspace_object *ps_self = (pspace_object *) self;
95
96 Py_XDECREF (ps_self->dict);
97 Py_XDECREF (ps_self->printers);
98 Py_XDECREF (ps_self->frame_filters);
99 Py_XDECREF (ps_self->frame_unwinders);
100 Py_XDECREF (ps_self->type_printers);
101 Py_XDECREF (ps_self->xmethods);
102 Py_TYPE (self)->tp_free (self);
103 }
104
105 /* Initialize a pspace_object.
106 The result is a boolean indicating success. */
107
108 static int
109 pspy_initialize (pspace_object *self)
110 {
111 self->pspace = NULL;
112
113 self->dict = PyDict_New ();
114 if (self->dict == NULL)
115 return 0;
116
117 self->printers = PyList_New (0);
118 if (self->printers == NULL)
119 return 0;
120
121 self->frame_filters = PyDict_New ();
122 if (self->frame_filters == NULL)
123 return 0;
124
125 self->frame_unwinders = PyList_New (0);
126 if (self->frame_unwinders == NULL)
127 return 0;
128
129 self->type_printers = PyList_New (0);
130 if (self->type_printers == NULL)
131 return 0;
132
133 self->xmethods = PyList_New (0);
134 if (self->xmethods == NULL)
135 return 0;
136
137 return 1;
138 }
139
140 static PyObject *
141 pspy_new (PyTypeObject *type, PyObject *args, PyObject *keywords)
142 {
143 gdbpy_ref<pspace_object> self ((pspace_object *) type->tp_alloc (type, 0));
144
145 if (self != NULL)
146 {
147 if (!pspy_initialize (self.get ()))
148 return NULL;
149 }
150
151 return (PyObject *) self.release ();
152 }
153
154 PyObject *
155 pspy_get_printers (PyObject *o, void *ignore)
156 {
157 pspace_object *self = (pspace_object *) o;
158
159 Py_INCREF (self->printers);
160 return self->printers;
161 }
162
163 static int
164 pspy_set_printers (PyObject *o, PyObject *value, void *ignore)
165 {
166 PyObject *tmp;
167 pspace_object *self = (pspace_object *) o;
168
169 if (! value)
170 {
171 PyErr_SetString (PyExc_TypeError,
172 "cannot delete the pretty_printers attribute");
173 return -1;
174 }
175
176 if (! PyList_Check (value))
177 {
178 PyErr_SetString (PyExc_TypeError,
179 "the pretty_printers attribute must be a list");
180 return -1;
181 }
182
183 /* Take care in case the LHS and RHS are related somehow. */
184 tmp = self->printers;
185 Py_INCREF (value);
186 self->printers = value;
187 Py_XDECREF (tmp);
188
189 return 0;
190 }
191
192 /* Return the Python dictionary attribute containing frame filters for
193 this program space. */
194 PyObject *
195 pspy_get_frame_filters (PyObject *o, void *ignore)
196 {
197 pspace_object *self = (pspace_object *) o;
198
199 Py_INCREF (self->frame_filters);
200 return self->frame_filters;
201 }
202
203 /* Set this object file's frame filters dictionary to FILTERS. */
204 static int
205 pspy_set_frame_filters (PyObject *o, PyObject *frame, void *ignore)
206 {
207 PyObject *tmp;
208 pspace_object *self = (pspace_object *) o;
209
210 if (! frame)
211 {
212 PyErr_SetString (PyExc_TypeError,
213 "cannot delete the frame filter attribute");
214 return -1;
215 }
216
217 if (! PyDict_Check (frame))
218 {
219 PyErr_SetString (PyExc_TypeError,
220 "the frame filter attribute must be a dictionary");
221 return -1;
222 }
223
224 /* Take care in case the LHS and RHS are related somehow. */
225 tmp = self->frame_filters;
226 Py_INCREF (frame);
227 self->frame_filters = frame;
228 Py_XDECREF (tmp);
229
230 return 0;
231 }
232
233 /* Return the list of the frame unwinders for this program space. */
234
235 PyObject *
236 pspy_get_frame_unwinders (PyObject *o, void *ignore)
237 {
238 pspace_object *self = (pspace_object *) o;
239
240 Py_INCREF (self->frame_unwinders);
241 return self->frame_unwinders;
242 }
243
244 /* Set this program space's list of the unwinders to UNWINDERS. */
245
246 static int
247 pspy_set_frame_unwinders (PyObject *o, PyObject *unwinders, void *ignore)
248 {
249 PyObject *tmp;
250 pspace_object *self = (pspace_object *) o;
251
252 if (!unwinders)
253 {
254 PyErr_SetString (PyExc_TypeError,
255 "cannot delete the frame unwinders list");
256 return -1;
257 }
258
259 if (!PyList_Check (unwinders))
260 {
261 PyErr_SetString (PyExc_TypeError,
262 "the frame unwinders attribute must be a list");
263 return -1;
264 }
265
266 /* Take care in case the LHS and RHS are related somehow. */
267 tmp = self->frame_unwinders;
268 Py_INCREF (unwinders);
269 self->frame_unwinders = unwinders;
270 Py_XDECREF (tmp);
271
272 return 0;
273 }
274
275 /* Get the 'type_printers' attribute. */
276
277 static PyObject *
278 pspy_get_type_printers (PyObject *o, void *ignore)
279 {
280 pspace_object *self = (pspace_object *) o;
281
282 Py_INCREF (self->type_printers);
283 return self->type_printers;
284 }
285
286 /* Get the 'xmethods' attribute. */
287
288 PyObject *
289 pspy_get_xmethods (PyObject *o, void *ignore)
290 {
291 pspace_object *self = (pspace_object *) o;
292
293 Py_INCREF (self->xmethods);
294 return self->xmethods;
295 }
296
297 /* Set the 'type_printers' attribute. */
298
299 static int
300 pspy_set_type_printers (PyObject *o, PyObject *value, void *ignore)
301 {
302 PyObject *tmp;
303 pspace_object *self = (pspace_object *) o;
304
305 if (! value)
306 {
307 PyErr_SetString (PyExc_TypeError,
308 "cannot delete the type_printers attribute");
309 return -1;
310 }
311
312 if (! PyList_Check (value))
313 {
314 PyErr_SetString (PyExc_TypeError,
315 "the type_printers attribute must be a list");
316 return -1;
317 }
318
319 /* Take care in case the LHS and RHS are related somehow. */
320 tmp = self->type_printers;
321 Py_INCREF (value);
322 self->type_printers = value;
323 Py_XDECREF (tmp);
324
325 return 0;
326 }
327
328 /* Implement the objfiles method. */
329
330 static PyObject *
331 pspy_get_objfiles (PyObject *self_, PyObject *args)
332 {
333 pspace_object *self = (pspace_object *) self_;
334
335 PSPY_REQUIRE_VALID (self);
336
337 gdbpy_ref<> list (PyList_New (0));
338 if (list == NULL)
339 return NULL;
340
341 if (self->pspace != NULL)
342 {
343 struct objfile *objf;
344
345 ALL_PSPACE_OBJFILES (self->pspace, objf)
346 {
347 PyObject *item = objfile_to_objfile_object (objf);
348
349 if (!item || PyList_Append (list.get (), item) == -1)
350 return NULL;
351 }
352 }
353
354 return list.release ();
355 }
356
357 /* Implementation of solib_name (Long) -> String.
358 Returns the name of the shared library holding a given address, or None. */
359
360 static PyObject *
361 pspy_solib_name (PyObject *o, PyObject *args)
362 {
363 char *soname;
364 gdb_py_longest pc;
365 pspace_object *self = (pspace_object *) o;
366
367 PSPY_REQUIRE_VALID (self);
368
369 if (!PyArg_ParseTuple (args, GDB_PY_LLU_ARG, &pc))
370 return NULL;
371
372 soname = solib_name_from_address (self->pspace, pc);
373 if (soname == nullptr)
374 Py_RETURN_NONE;
375 return host_string_to_python_string (soname);
376 }
377
378 /* Return the innermost lexical block containing the specified pc value,
379 or 0 if there is none. */
380 static PyObject *
381 pspy_block_for_pc (PyObject *o, PyObject *args)
382 {
383 pspace_object *self = (pspace_object *) o;
384 gdb_py_ulongest pc;
385 const struct block *block = NULL;
386 struct compunit_symtab *cust = NULL;
387
388 PSPY_REQUIRE_VALID (self);
389
390 if (!PyArg_ParseTuple (args, GDB_PY_LLU_ARG, &pc))
391 return NULL;
392
393 TRY
394 {
395 scoped_restore_current_program_space saver;
396
397 set_current_program_space (self->pspace);
398 cust = find_pc_compunit_symtab (pc);
399
400 if (cust != NULL && COMPUNIT_OBJFILE (cust) != NULL)
401 block = block_for_pc (pc);
402 }
403 CATCH (except, RETURN_MASK_ALL)
404 {
405 GDB_PY_HANDLE_EXCEPTION (except);
406 }
407 END_CATCH
408
409 if (cust == NULL || COMPUNIT_OBJFILE (cust) == NULL)
410 {
411 PyErr_SetString (PyExc_RuntimeError,
412 _("Cannot locate object file for block."));
413 return NULL;
414 }
415
416 if (block)
417 return block_to_block_object (block, COMPUNIT_OBJFILE (cust));
418
419 Py_RETURN_NONE;
420 }
421
422 /* Implementation of the find_pc_line function.
423 Returns the gdb.Symtab_and_line object corresponding to a PC value. */
424
425 static PyObject *
426 pspy_find_pc_line (PyObject *o, PyObject *args)
427 {
428 gdb_py_ulongest pc_llu;
429 PyObject *result = NULL; /* init for gcc -Wall */
430 pspace_object *self = (pspace_object *) o;
431
432 PSPY_REQUIRE_VALID (self);
433
434 if (!PyArg_ParseTuple (args, GDB_PY_LLU_ARG, &pc_llu))
435 return NULL;
436
437 TRY
438 {
439 struct symtab_and_line sal;
440 CORE_ADDR pc;
441 scoped_restore_current_program_space saver;
442
443 set_current_program_space (self->pspace);
444
445 pc = (CORE_ADDR) pc_llu;
446 sal = find_pc_line (pc, 0);
447 result = symtab_and_line_to_sal_object (sal);
448 }
449 CATCH (except, RETURN_MASK_ALL)
450 {
451 GDB_PY_HANDLE_EXCEPTION (except);
452 }
453 END_CATCH
454
455 return result;
456 }
457
458 /* Implementation of is_valid (self) -> Boolean.
459 Returns True if this program space still exists in GDB. */
460
461 static PyObject *
462 pspy_is_valid (PyObject *o, PyObject *args)
463 {
464 pspace_object *self = (pspace_object *) o;
465
466 if (self->pspace == NULL)
467 Py_RETURN_FALSE;
468
469 Py_RETURN_TRUE;
470 }
471
472 \f
473
474 /* Clear the PSPACE pointer in a Pspace object and remove the reference. */
475
476 static void
477 py_free_pspace (struct program_space *pspace, void *datum)
478 {
479 /* This is a fiction, but we're in a nasty spot: The pspace is in the
480 process of being deleted, we can't rely on anything in it. Plus
481 this is one time when the current program space and current inferior
482 are not in sync: All inferiors that use PSPACE may no longer exist.
483 We don't need to do much here, and since "there is always an inferior"
484 using target_gdbarch suffices.
485 Note: We cannot call get_current_arch because it may try to access
486 the target, which may involve accessing data in the pspace currently
487 being deleted. */
488 struct gdbarch *arch = target_gdbarch ();
489
490 gdbpy_enter enter_py (arch, current_language);
491 gdbpy_ref<pspace_object> object ((pspace_object *) datum);
492 object->pspace = NULL;
493 }
494
495 /* Return a borrowed reference to the Python object of type Pspace
496 representing PSPACE. If the object has already been created,
497 return it. Otherwise, create it. Return NULL and set the Python
498 error on failure. */
499
500 PyObject *
501 pspace_to_pspace_object (struct program_space *pspace)
502 {
503 gdbpy_ref<pspace_object> object
504 ((pspace_object *) program_space_data (pspace, pspy_pspace_data_key));
505 if (object == NULL)
506 {
507 object.reset (PyObject_New (pspace_object, &pspace_object_type));
508 if (object != NULL)
509 {
510 if (!pspy_initialize (object.get ()))
511 return NULL;
512
513 object->pspace = pspace;
514 set_program_space_data (pspace, pspy_pspace_data_key, object.get ());
515 }
516 }
517
518 return (PyObject *) object.release ();
519 }
520
521 int
522 gdbpy_initialize_pspace (void)
523 {
524 pspy_pspace_data_key
525 = register_program_space_data_with_cleanup (NULL, py_free_pspace);
526
527 if (PyType_Ready (&pspace_object_type) < 0)
528 return -1;
529
530 return gdb_pymodule_addobject (gdb_module, "Progspace",
531 (PyObject *) &pspace_object_type);
532 }
533
534 \f
535
536 static gdb_PyGetSetDef pspace_getset[] =
537 {
538 { "__dict__", gdb_py_generic_dict, NULL,
539 "The __dict__ for this progspace.", &pspace_object_type },
540 { "filename", pspy_get_filename, NULL,
541 "The progspace's main filename, or None.", NULL },
542 { "pretty_printers", pspy_get_printers, pspy_set_printers,
543 "Pretty printers.", NULL },
544 { "frame_filters", pspy_get_frame_filters, pspy_set_frame_filters,
545 "Frame filters.", NULL },
546 { "frame_unwinders", pspy_get_frame_unwinders, pspy_set_frame_unwinders,
547 "Frame unwinders.", NULL },
548 { "type_printers", pspy_get_type_printers, pspy_set_type_printers,
549 "Type printers.", NULL },
550 { "xmethods", pspy_get_xmethods, NULL,
551 "Debug methods.", NULL },
552 { NULL }
553 };
554
555 static PyMethodDef progspace_object_methods[] =
556 {
557 { "objfiles", pspy_get_objfiles, METH_NOARGS,
558 "Return a sequence of objfiles associated to this program space." },
559 { "solib_name", pspy_solib_name, METH_VARARGS,
560 "solib_name (Long) -> String.\n\
561 Return the name of the shared library holding a given address, or None." },
562 { "block_for_pc", pspy_block_for_pc, METH_VARARGS,
563 "Return the block containing the given pc value, or None." },
564 { "find_pc_line", pspy_find_pc_line, METH_VARARGS,
565 "find_pc_line (pc) -> Symtab_and_line.\n\
566 Return the gdb.Symtab_and_line object corresponding to the pc value." },
567 { "is_valid", pspy_is_valid, METH_NOARGS,
568 "is_valid () -> Boolean.\n\
569 Return true if this program space is valid, false if not." },
570 { NULL }
571 };
572
573 PyTypeObject pspace_object_type =
574 {
575 PyVarObject_HEAD_INIT (NULL, 0)
576 "gdb.Progspace", /*tp_name*/
577 sizeof (pspace_object), /*tp_basicsize*/
578 0, /*tp_itemsize*/
579 pspy_dealloc, /*tp_dealloc*/
580 0, /*tp_print*/
581 0, /*tp_getattr*/
582 0, /*tp_setattr*/
583 0, /*tp_compare*/
584 0, /*tp_repr*/
585 0, /*tp_as_number*/
586 0, /*tp_as_sequence*/
587 0, /*tp_as_mapping*/
588 0, /*tp_hash */
589 0, /*tp_call*/
590 0, /*tp_str*/
591 0, /*tp_getattro*/
592 0, /*tp_setattro*/
593 0, /*tp_as_buffer*/
594 Py_TPFLAGS_DEFAULT, /*tp_flags*/
595 "GDB progspace object", /* tp_doc */
596 0, /* tp_traverse */
597 0, /* tp_clear */
598 0, /* tp_richcompare */
599 0, /* tp_weaklistoffset */
600 0, /* tp_iter */
601 0, /* tp_iternext */
602 progspace_object_methods, /* tp_methods */
603 0, /* tp_members */
604 pspace_getset, /* tp_getset */
605 0, /* tp_base */
606 0, /* tp_dict */
607 0, /* tp_descr_get */
608 0, /* tp_descr_set */
609 offsetof (pspace_object, dict), /* tp_dictoffset */
610 0, /* tp_init */
611 0, /* tp_alloc */
612 pspy_new, /* tp_new */
613 };
This page took 0.045126 seconds and 4 git commands to generate.