1 /* Python interface to blocks.
3 Copyright (C) 2008-2016 Free Software Foundation, Inc.
5 This file is part of GDB.
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.
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.
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/>. */
22 #include "dictionary.h"
24 #include "python-internal.h"
28 typedef struct blpy_block_object {
30 /* The GDB block structure that represents a frame's code block. */
31 const struct block *block;
32 /* The backing object file. There is no direct relationship in GDB
33 between a block and an object file. When a block is created also
34 store a pointer to the object file for later use. */
35 struct objfile *objfile;
36 /* Keep track of all blocks with a doubly-linked list. Needed for
37 block invalidation if the source object file has been freed. */
38 struct blpy_block_object *prev;
39 struct blpy_block_object *next;
45 const struct block *block;
46 /* The iterator for that block. */
47 struct block_iterator iter;
48 /* Has the iterator been initialized flag. */
50 /* Pointer back to the original source block object. Needed to
51 check if the block is still valid, and has not been invalidated
52 when an object file has been freed. */
53 struct blpy_block_object *source;
54 } block_syms_iterator_object;
56 /* Require a valid block. All access to block_object->block should be
57 gated by this call. */
58 #define BLPY_REQUIRE_VALID(block_obj, block) \
60 block = block_object_to_block (block_obj); \
63 PyErr_SetString (PyExc_RuntimeError, \
64 _("Block is invalid.")); \
69 /* Require a valid block. This macro is called during block iterator
70 creation, and at each next call. */
71 #define BLPY_ITER_REQUIRE_VALID(block_obj) \
73 if (block_obj->block == NULL) \
75 PyErr_SetString (PyExc_RuntimeError, \
76 _("Source block for iterator is invalid.")); \
81 extern PyTypeObject block_syms_iterator_object_type
82 CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("block_syms_iterator_object");
83 static const struct objfile_data *blpy_objfile_data_key;
86 blpy_iter (PyObject *self)
88 block_syms_iterator_object *block_iter_obj;
89 const struct block *block = NULL;
91 BLPY_REQUIRE_VALID (self, block);
93 block_iter_obj = PyObject_New (block_syms_iterator_object,
94 &block_syms_iterator_object_type);
95 if (block_iter_obj == NULL)
98 block_iter_obj->block = block;
99 block_iter_obj->initialized_p = 0;
101 block_iter_obj->source = (block_object *) self;
103 return (PyObject *) block_iter_obj;
107 blpy_get_start (PyObject *self, void *closure)
109 const struct block *block = NULL;
111 BLPY_REQUIRE_VALID (self, block);
113 return gdb_py_object_from_ulongest (BLOCK_START (block));
117 blpy_get_end (PyObject *self, void *closure)
119 const struct block *block = NULL;
121 BLPY_REQUIRE_VALID (self, block);
123 return gdb_py_object_from_ulongest (BLOCK_END (block));
127 blpy_get_function (PyObject *self, void *closure)
130 const struct block *block;
132 BLPY_REQUIRE_VALID (self, block);
134 sym = BLOCK_FUNCTION (block);
136 return symbol_to_symbol_object (sym);
142 blpy_get_superblock (PyObject *self, void *closure)
144 const struct block *block;
145 const struct block *super_block;
146 block_object *self_obj = (block_object *) self;
148 BLPY_REQUIRE_VALID (self, block);
150 super_block = BLOCK_SUPERBLOCK (block);
152 return block_to_block_object (super_block, self_obj->objfile);
157 /* Return the global block associated to this block. */
160 blpy_get_global_block (PyObject *self, void *closure)
162 const struct block *block;
163 const struct block *global_block;
164 block_object *self_obj = (block_object *) self;
166 BLPY_REQUIRE_VALID (self, block);
168 global_block = block_global_block (block);
170 return block_to_block_object (global_block,
175 /* Return the static block associated to this block. Return None
176 if we cannot get the static block (this is the global block). */
179 blpy_get_static_block (PyObject *self, void *closure)
181 const struct block *block;
182 const struct block *static_block;
183 block_object *self_obj = (block_object *) self;
185 BLPY_REQUIRE_VALID (self, block);
187 if (BLOCK_SUPERBLOCK (block) == NULL)
190 static_block = block_static_block (block);
192 return block_to_block_object (static_block, self_obj->objfile);
195 /* Implementation of gdb.Block.is_global (self) -> Boolean.
196 Returns True if this block object is a global block. */
199 blpy_is_global (PyObject *self, void *closure)
201 const struct block *block;
203 BLPY_REQUIRE_VALID (self, block);
205 if (BLOCK_SUPERBLOCK (block))
211 /* Implementation of gdb.Block.is_static (self) -> Boolean.
212 Returns True if this block object is a static block. */
215 blpy_is_static (PyObject *self, void *closure)
217 const struct block *block;
219 BLPY_REQUIRE_VALID (self, block);
221 if (BLOCK_SUPERBLOCK (block) != NULL
222 && BLOCK_SUPERBLOCK (BLOCK_SUPERBLOCK (block)) == NULL)
229 blpy_dealloc (PyObject *obj)
231 block_object *block = (block_object *) obj;
234 block->prev->next = block->next;
235 else if (block->objfile)
237 set_objfile_data (block->objfile, blpy_objfile_data_key,
241 block->next->prev = block->prev;
245 /* Given a block, and a block_object that has previously been
246 allocated and initialized, populate the block_object with the
247 struct block data. Also, register the block_object life-cycle
248 with the life-cycle of the object file associated with this
251 set_block (block_object *obj, const struct block *block,
252 struct objfile *objfile)
258 obj->objfile = objfile;
259 obj->next = ((struct blpy_block_object *)
260 objfile_data (objfile, blpy_objfile_data_key));
262 obj->next->prev = obj;
263 set_objfile_data (objfile, blpy_objfile_data_key, obj);
269 /* Create a new block object (gdb.Block) that encapsulates the struct
270 block object from GDB. */
272 block_to_block_object (const struct block *block, struct objfile *objfile)
274 block_object *block_obj;
276 block_obj = PyObject_New (block_object, &block_object_type);
278 set_block (block_obj, block, objfile);
280 return (PyObject *) block_obj;
283 /* Return struct block reference that is wrapped by this object. */
285 block_object_to_block (PyObject *obj)
287 if (! PyObject_TypeCheck (obj, &block_object_type))
289 return ((block_object *) obj)->block;
292 /* Return a reference to the block iterator. */
294 blpy_block_syms_iter (PyObject *self)
296 block_syms_iterator_object *iter_obj = (block_syms_iterator_object *) self;
298 BLPY_ITER_REQUIRE_VALID (iter_obj->source);
304 /* Return the next symbol in the iteration through the block's
307 blpy_block_syms_iternext (PyObject *self)
309 block_syms_iterator_object *iter_obj = (block_syms_iterator_object *) self;
312 BLPY_ITER_REQUIRE_VALID (iter_obj->source);
314 if (!iter_obj->initialized_p)
316 sym = block_iterator_first (iter_obj->block, &(iter_obj->iter));
317 iter_obj->initialized_p = 1;
320 sym = block_iterator_next (&(iter_obj->iter));
324 PyErr_SetString (PyExc_StopIteration, _("Symbol is null."));
328 return symbol_to_symbol_object (sym);
332 blpy_block_syms_dealloc (PyObject *obj)
334 block_syms_iterator_object *iter_obj = (block_syms_iterator_object *) obj;
336 Py_XDECREF (iter_obj->source);
339 /* Implementation of gdb.Block.is_valid (self) -> Boolean.
340 Returns True if this block object still exists in GDB. */
343 blpy_is_valid (PyObject *self, PyObject *args)
345 const struct block *block;
347 block = block_object_to_block (self);
354 /* Implementation of gdb.BlockIterator.is_valid (self) -> Boolean.
355 Returns True if this block iterator object still exists in GDB */
358 blpy_iter_is_valid (PyObject *self, PyObject *args)
360 block_syms_iterator_object *iter_obj =
361 (block_syms_iterator_object *) self;
363 if (iter_obj->source->block == NULL)
369 /* Return the innermost lexical block containing the specified pc value,
370 or 0 if there is none. */
372 gdbpy_block_for_pc (PyObject *self, PyObject *args)
375 const struct block *block = NULL;
376 struct compunit_symtab *cust = NULL;
378 if (!PyArg_ParseTuple (args, GDB_PY_LLU_ARG, &pc))
383 cust = find_pc_compunit_symtab (pc);
385 if (cust != NULL && COMPUNIT_OBJFILE (cust) != NULL)
386 block = block_for_pc (pc);
388 CATCH (except, RETURN_MASK_ALL)
390 GDB_PY_HANDLE_EXCEPTION (except);
394 if (cust == NULL || COMPUNIT_OBJFILE (cust) == NULL)
396 PyErr_SetString (PyExc_RuntimeError,
397 _("Cannot locate object file for block."));
402 return block_to_block_object (block, COMPUNIT_OBJFILE (cust));
407 /* This function is called when an objfile is about to be freed.
408 Invalidate the block as further actions on the block would result
409 in bad data. All access to obj->symbol should be gated by
410 BLPY_REQUIRE_VALID which will raise an exception on invalid
413 del_objfile_blocks (struct objfile *objfile, void *datum)
415 block_object *obj = (block_object *) datum;
419 block_object *next = obj->next;
431 gdbpy_initialize_blocks (void)
433 block_object_type.tp_new = PyType_GenericNew;
434 if (PyType_Ready (&block_object_type) < 0)
437 block_syms_iterator_object_type.tp_new = PyType_GenericNew;
438 if (PyType_Ready (&block_syms_iterator_object_type) < 0)
441 /* Register an objfile "free" callback so we can properly
442 invalidate blocks when an object file is about to be
444 blpy_objfile_data_key
445 = register_objfile_data_with_cleanup (NULL, del_objfile_blocks);
447 if (gdb_pymodule_addobject (gdb_module, "Block",
448 (PyObject *) &block_object_type) < 0)
451 return gdb_pymodule_addobject (gdb_module, "BlockIterator",
452 (PyObject *) &block_syms_iterator_object_type);
457 static PyMethodDef block_object_methods[] = {
458 { "is_valid", blpy_is_valid, METH_NOARGS,
459 "is_valid () -> Boolean.\n\
460 Return true if this block is valid, false if not." },
461 {NULL} /* Sentinel */
464 static PyGetSetDef block_object_getset[] = {
465 { "start", blpy_get_start, NULL, "Start address of the block.", NULL },
466 { "end", blpy_get_end, NULL, "End address of the block.", NULL },
467 { "function", blpy_get_function, NULL,
468 "Symbol that names the block, or None.", NULL },
469 { "superblock", blpy_get_superblock, NULL,
470 "Block containing the block, or None.", NULL },
471 { "global_block", blpy_get_global_block, NULL,
472 "Block containing the global block.", NULL },
473 { "static_block", blpy_get_static_block, NULL,
474 "Block containing the static block.", NULL },
475 { "is_static", blpy_is_static, NULL,
476 "Whether this block is a static block.", NULL },
477 { "is_global", blpy_is_global, NULL,
478 "Whether this block is a global block.", NULL },
479 { NULL } /* Sentinel */
482 PyTypeObject block_object_type = {
483 PyVarObject_HEAD_INIT (NULL, 0)
484 "gdb.Block", /*tp_name*/
485 sizeof (block_object), /*tp_basicsize*/
487 blpy_dealloc, /*tp_dealloc*/
494 0, /*tp_as_sequence*/
502 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_ITER, /*tp_flags*/
503 "GDB block object", /* tp_doc */
506 0, /* tp_richcompare */
507 0, /* tp_weaklistoffset */
508 blpy_iter, /* tp_iter */
510 block_object_methods, /* tp_methods */
512 block_object_getset /* tp_getset */
515 static PyMethodDef block_iterator_object_methods[] = {
516 { "is_valid", blpy_iter_is_valid, METH_NOARGS,
517 "is_valid () -> Boolean.\n\
518 Return true if this block iterator is valid, false if not." },
519 {NULL} /* Sentinel */
522 PyTypeObject block_syms_iterator_object_type = {
523 PyVarObject_HEAD_INIT (NULL, 0)
524 "gdb.BlockIterator", /*tp_name*/
525 sizeof (block_syms_iterator_object), /*tp_basicsize*/
527 blpy_block_syms_dealloc, /*tp_dealloc*/
534 0, /*tp_as_sequence*/
542 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_ITER, /*tp_flags*/
543 "GDB block syms iterator object", /*tp_doc */
546 0, /*tp_richcompare */
547 0, /*tp_weaklistoffset */
548 blpy_block_syms_iter, /*tp_iter */
549 blpy_block_syms_iternext, /*tp_iternext */
550 block_iterator_object_methods /*tp_methods */