xref: /dragonfly/contrib/gdb-7/gdb/python/py-block.c (revision 6ca88057)
1 /* Python interface to blocks.
2 
3    Copyright (C) 2008-2013 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 "block.h"
22 #include "dictionary.h"
23 #include "symtab.h"
24 #include "python-internal.h"
25 #include "objfiles.h"
26 #include "symtab.h"
27 
28 typedef struct blpy_block_object {
29   PyObject_HEAD
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;
40 } block_object;
41 
42 typedef struct {
43   PyObject_HEAD
44   /* The block.  */
45   const struct block *block;
46   /* The iterator for that block.  */
47   struct block_iterator iter;
48   /* Has the iterator been initialized flag.  */
49   int initialized_p;
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;
55 
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)		\
59   do {							\
60     block = block_object_to_block (block_obj);		\
61     if (block == NULL)					\
62       {							\
63 	PyErr_SetString (PyExc_RuntimeError,		\
64 			 _("Block is invalid."));	\
65 	return NULL;					\
66       }							\
67   } while (0)
68 
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)				\
72   do {									\
73     if (block_obj->block == NULL)					\
74       {									\
75 	PyErr_SetString (PyExc_RuntimeError,				\
76 			 _("Source block for iterator is invalid."));	\
77 	return NULL;							\
78       }									\
79   } while (0)
80 
81 static PyTypeObject block_syms_iterator_object_type;
82 static const struct objfile_data *blpy_objfile_data_key;
83 
84 static PyObject *
85 blpy_iter (PyObject *self)
86 {
87   block_syms_iterator_object *block_iter_obj;
88   const struct block *block = NULL;
89 
90   BLPY_REQUIRE_VALID (self, block);
91 
92   block_iter_obj = PyObject_New (block_syms_iterator_object,
93 				 &block_syms_iterator_object_type);
94   if (block_iter_obj == NULL)
95       return NULL;
96 
97   block_iter_obj->block = block;
98   block_iter_obj->initialized_p = 0;
99   Py_INCREF (self);
100   block_iter_obj->source = (block_object *) self;
101 
102   return (PyObject *) block_iter_obj;
103 }
104 
105 static PyObject *
106 blpy_get_start (PyObject *self, void *closure)
107 {
108   const struct block *block = NULL;
109 
110   BLPY_REQUIRE_VALID (self, block);
111 
112   return gdb_py_object_from_ulongest (BLOCK_START (block));
113 }
114 
115 static PyObject *
116 blpy_get_end (PyObject *self, void *closure)
117 {
118   const struct block *block = NULL;
119 
120   BLPY_REQUIRE_VALID (self, block);
121 
122   return gdb_py_object_from_ulongest (BLOCK_END (block));
123 }
124 
125 static PyObject *
126 blpy_get_function (PyObject *self, void *closure)
127 {
128   struct symbol *sym;
129   const struct block *block;
130 
131   BLPY_REQUIRE_VALID (self, block);
132 
133   sym = BLOCK_FUNCTION (block);
134   if (sym)
135     return symbol_to_symbol_object (sym);
136 
137   Py_RETURN_NONE;
138 }
139 
140 static PyObject *
141 blpy_get_superblock (PyObject *self, void *closure)
142 {
143   const struct block *block;
144   const struct block *super_block;
145   block_object *self_obj  = (block_object *) self;
146 
147   BLPY_REQUIRE_VALID (self, block);
148 
149   super_block = BLOCK_SUPERBLOCK (block);
150   if (super_block)
151     return block_to_block_object (super_block, self_obj->objfile);
152 
153   Py_RETURN_NONE;
154 }
155 
156 /* Return the global block associated to this block.  */
157 
158 static PyObject *
159 blpy_get_global_block (PyObject *self, void *closure)
160 {
161   const struct block *block;
162   const struct block *global_block;
163   block_object *self_obj  = (block_object *) self;
164 
165   BLPY_REQUIRE_VALID (self, block);
166 
167   global_block = block_global_block (block);
168 
169   return block_to_block_object (global_block,
170 				self_obj->objfile);
171 
172 }
173 
174 /* Return the static block associated to this block.  Return None
175    if we cannot get the static block (this is the global block).  */
176 
177 static PyObject *
178 blpy_get_static_block (PyObject *self, void *closure)
179 {
180   const struct block *block;
181   const struct block *static_block;
182   block_object *self_obj  = (block_object *) self;
183 
184   BLPY_REQUIRE_VALID (self, block);
185 
186   if (BLOCK_SUPERBLOCK (block) == NULL)
187     Py_RETURN_NONE;
188 
189   static_block = block_static_block (block);
190 
191   return block_to_block_object (static_block, self_obj->objfile);
192 }
193 
194 /* Implementation of gdb.Block.is_global (self) -> Boolean.
195    Returns True if this block object is a global block.  */
196 
197 static PyObject *
198 blpy_is_global (PyObject *self, void *closure)
199 {
200   const struct block *block;
201 
202   BLPY_REQUIRE_VALID (self, block);
203 
204   if (BLOCK_SUPERBLOCK (block))
205     Py_RETURN_FALSE;
206 
207   Py_RETURN_TRUE;
208 }
209 
210 /* Implementation of gdb.Block.is_static (self) -> Boolean.
211    Returns True if this block object is a static block.  */
212 
213 static PyObject *
214 blpy_is_static (PyObject *self, void *closure)
215 {
216   const struct block *block;
217 
218   BLPY_REQUIRE_VALID (self, block);
219 
220   if (BLOCK_SUPERBLOCK (block) != NULL
221      && BLOCK_SUPERBLOCK (BLOCK_SUPERBLOCK (block)) == NULL)
222     Py_RETURN_TRUE;
223 
224   Py_RETURN_FALSE;
225 }
226 
227 static void
228 blpy_dealloc (PyObject *obj)
229 {
230   block_object *block = (block_object *) obj;
231 
232   if (block->prev)
233     block->prev->next = block->next;
234   else if (block->objfile)
235     {
236       set_objfile_data (block->objfile, blpy_objfile_data_key,
237 			block->next);
238     }
239   if (block->next)
240     block->next->prev = block->prev;
241   block->block = NULL;
242 }
243 
244 /* Given a block, and a block_object that has previously been
245    allocated and initialized, populate the block_object with the
246    struct block data.  Also, register the block_object life-cycle
247    with the life-cycle of the object file associated with this
248    block, if needed.  */
249 static void
250 set_block (block_object *obj, const struct block *block,
251 	   struct objfile *objfile)
252 {
253   obj->block = block;
254   obj->prev = NULL;
255   if (objfile)
256     {
257       obj->objfile = objfile;
258       obj->next = objfile_data (objfile, blpy_objfile_data_key);
259       if (obj->next)
260 	obj->next->prev = obj;
261       set_objfile_data (objfile, blpy_objfile_data_key, obj);
262     }
263   else
264     obj->next = NULL;
265 }
266 
267 /* Create a new block object (gdb.Block) that encapsulates the struct
268    block object from GDB.  */
269 PyObject *
270 block_to_block_object (const struct block *block, struct objfile *objfile)
271 {
272   block_object *block_obj;
273 
274   block_obj = PyObject_New (block_object, &block_object_type);
275   if (block_obj)
276     set_block (block_obj, block, objfile);
277 
278   return (PyObject *) block_obj;
279 }
280 
281 /* Return struct block reference that is wrapped by this object.  */
282 const struct block *
283 block_object_to_block (PyObject *obj)
284 {
285   if (! PyObject_TypeCheck (obj, &block_object_type))
286     return NULL;
287   return ((block_object *) obj)->block;
288 }
289 
290 /* Return a reference to the block iterator.  */
291 static PyObject *
292 blpy_block_syms_iter (PyObject *self)
293 {
294   block_syms_iterator_object *iter_obj = (block_syms_iterator_object *) self;
295 
296   BLPY_ITER_REQUIRE_VALID (iter_obj->source);
297 
298   Py_INCREF (self);
299   return self;
300 }
301 
302 /* Return the next symbol in the iteration through the block's
303    dictionary.  */
304 static PyObject *
305 blpy_block_syms_iternext (PyObject *self)
306 {
307   block_syms_iterator_object *iter_obj = (block_syms_iterator_object *) self;
308   struct symbol *sym;
309 
310   BLPY_ITER_REQUIRE_VALID (iter_obj->source);
311 
312   if (!iter_obj->initialized_p)
313     {
314       sym = block_iterator_first (iter_obj->block,  &(iter_obj->iter));
315       iter_obj->initialized_p = 1;
316     }
317   else
318     sym = block_iterator_next (&(iter_obj->iter));
319 
320   if (sym == NULL)
321     {
322       PyErr_SetString (PyExc_StopIteration, _("Symbol is null."));
323       return NULL;
324     }
325 
326   return symbol_to_symbol_object (sym);
327 }
328 
329 static void
330 blpy_block_syms_dealloc (PyObject *obj)
331 {
332   block_syms_iterator_object *iter_obj = (block_syms_iterator_object *) obj;
333 
334   Py_XDECREF (iter_obj->source);
335 }
336 
337 /* Implementation of gdb.Block.is_valid (self) -> Boolean.
338    Returns True if this block object still exists in GDB.  */
339 
340 static PyObject *
341 blpy_is_valid (PyObject *self, PyObject *args)
342 {
343   const struct block *block;
344 
345   block = block_object_to_block (self);
346   if (block == NULL)
347     Py_RETURN_FALSE;
348 
349   Py_RETURN_TRUE;
350 }
351 
352 /* Implementation of gdb.BlockIterator.is_valid (self) -> Boolean.
353    Returns True if this block iterator object still exists in GDB  */
354 
355 static PyObject *
356 blpy_iter_is_valid (PyObject *self, PyObject *args)
357 {
358   block_syms_iterator_object *iter_obj =
359     (block_syms_iterator_object *) self;
360 
361   if (iter_obj->source->block == NULL)
362     Py_RETURN_FALSE;
363 
364   Py_RETURN_TRUE;
365 }
366 
367 /* Return the innermost lexical block containing the specified pc value,
368    or 0 if there is none.  */
369 PyObject *
370 gdbpy_block_for_pc (PyObject *self, PyObject *args)
371 {
372   gdb_py_ulongest pc;
373   struct block *block = NULL;
374   struct obj_section *section = NULL;
375   struct symtab *symtab = NULL;
376   volatile struct gdb_exception except;
377 
378   if (!PyArg_ParseTuple (args, GDB_PY_LLU_ARG, &pc))
379     return NULL;
380 
381   TRY_CATCH (except, RETURN_MASK_ALL)
382     {
383       section = find_pc_mapped_section (pc);
384       symtab = find_pc_sect_symtab (pc, section);
385 
386       if (symtab != NULL && symtab->objfile != NULL)
387 	block = block_for_pc (pc);
388     }
389   GDB_PY_HANDLE_EXCEPTION (except);
390 
391   if (!symtab || symtab->objfile == NULL)
392     {
393       PyErr_SetString (PyExc_RuntimeError,
394 		       _("Cannot locate object file for block."));
395       return NULL;
396     }
397 
398   if (block)
399     return block_to_block_object (block, symtab->objfile);
400 
401   Py_RETURN_NONE;
402 }
403 
404 /* This function is called when an objfile is about to be freed.
405    Invalidate the block as further actions on the block would result
406    in bad data.  All access to obj->symbol should be gated by
407    BLPY_REQUIRE_VALID which will raise an exception on invalid
408    blocks.  */
409 static void
410 del_objfile_blocks (struct objfile *objfile, void *datum)
411 {
412   block_object *obj = datum;
413 
414   while (obj)
415     {
416       block_object *next = obj->next;
417 
418       obj->block = NULL;
419       obj->objfile = NULL;
420       obj->next = NULL;
421       obj->prev = NULL;
422 
423       obj = next;
424     }
425 }
426 
427 void
428 gdbpy_initialize_blocks (void)
429 {
430   block_object_type.tp_new = PyType_GenericNew;
431   if (PyType_Ready (&block_object_type) < 0)
432     return;
433 
434   block_syms_iterator_object_type.tp_new = PyType_GenericNew;
435   if (PyType_Ready (&block_syms_iterator_object_type) < 0)
436     return;
437 
438   /* Register an objfile "free" callback so we can properly
439      invalidate blocks when an object file is about to be
440      deleted.  */
441   blpy_objfile_data_key
442     = register_objfile_data_with_cleanup (NULL, del_objfile_blocks);
443 
444   Py_INCREF (&block_object_type);
445   PyModule_AddObject (gdb_module, "Block", (PyObject *) &block_object_type);
446 
447   Py_INCREF (&block_syms_iterator_object_type);
448   PyModule_AddObject (gdb_module, "BlockIterator",
449 		      (PyObject *) &block_syms_iterator_object_type);
450 }
451 
452 
453 
454 static PyMethodDef block_object_methods[] = {
455   { "is_valid", blpy_is_valid, METH_NOARGS,
456     "is_valid () -> Boolean.\n\
457 Return true if this block is valid, false if not." },
458   {NULL}  /* Sentinel */
459 };
460 
461 static PyGetSetDef block_object_getset[] = {
462   { "start", blpy_get_start, NULL, "Start address of the block.", NULL },
463   { "end", blpy_get_end, NULL, "End address of the block.", NULL },
464   { "function", blpy_get_function, NULL,
465     "Symbol that names the block, or None.", NULL },
466   { "superblock", blpy_get_superblock, NULL,
467     "Block containing the block, or None.", NULL },
468   { "global_block", blpy_get_global_block, NULL,
469     "Block containing the global block.", NULL },
470   { "static_block", blpy_get_static_block, NULL,
471     "Block containing the static block.", NULL },
472   { "is_static", blpy_is_static, NULL,
473     "Whether this block is a static block.", NULL },
474   { "is_global", blpy_is_global, NULL,
475     "Whether this block is a global block.", NULL },
476   { NULL }  /* Sentinel */
477 };
478 
479 PyTypeObject block_object_type = {
480   PyVarObject_HEAD_INIT (NULL, 0)
481   "gdb.Block",			  /*tp_name*/
482   sizeof (block_object),	  /*tp_basicsize*/
483   0,				  /*tp_itemsize*/
484   blpy_dealloc,                   /*tp_dealloc*/
485   0,				  /*tp_print*/
486   0,				  /*tp_getattr*/
487   0,				  /*tp_setattr*/
488   0,				  /*tp_compare*/
489   0,				  /*tp_repr*/
490   0,				  /*tp_as_number*/
491   0,				  /*tp_as_sequence*/
492   0,				  /*tp_as_mapping*/
493   0,				  /*tp_hash */
494   0,				  /*tp_call*/
495   0,				  /*tp_str*/
496   0,				  /*tp_getattro*/
497   0,				  /*tp_setattro*/
498   0,				  /*tp_as_buffer*/
499   Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_ITER,  /*tp_flags*/
500   "GDB block object",		  /* tp_doc */
501   0,				  /* tp_traverse */
502   0,				  /* tp_clear */
503   0,				  /* tp_richcompare */
504   0,				  /* tp_weaklistoffset */
505   blpy_iter,			  /* tp_iter */
506   0,				  /* tp_iternext */
507   block_object_methods,		  /* tp_methods */
508   0,				  /* tp_members */
509   block_object_getset		  /* tp_getset */
510 };
511 
512 static PyMethodDef block_iterator_object_methods[] = {
513   { "is_valid", blpy_iter_is_valid, METH_NOARGS,
514     "is_valid () -> Boolean.\n\
515 Return true if this block iterator is valid, false if not." },
516   {NULL}  /* Sentinel */
517 };
518 
519 static PyTypeObject block_syms_iterator_object_type = {
520   PyVarObject_HEAD_INIT (NULL, 0)
521   "gdb.BlockIterator",		  /*tp_name*/
522   sizeof (block_syms_iterator_object),	      /*tp_basicsize*/
523   0,				  /*tp_itemsize*/
524   blpy_block_syms_dealloc,	  /*tp_dealloc*/
525   0,				  /*tp_print*/
526   0,				  /*tp_getattr*/
527   0,				  /*tp_setattr*/
528   0,				  /*tp_compare*/
529   0,				  /*tp_repr*/
530   0,				  /*tp_as_number*/
531   0,				  /*tp_as_sequence*/
532   0,				  /*tp_as_mapping*/
533   0,				  /*tp_hash */
534   0,				  /*tp_call*/
535   0,				  /*tp_str*/
536   0,				  /*tp_getattro*/
537   0,				  /*tp_setattro*/
538   0,				  /*tp_as_buffer*/
539   Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_ITER,  /*tp_flags*/
540   "GDB block syms iterator object",	      /*tp_doc */
541   0,				  /*tp_traverse */
542   0,				  /*tp_clear */
543   0,				  /*tp_richcompare */
544   0,				  /*tp_weaklistoffset */
545   blpy_block_syms_iter,           /*tp_iter */
546   blpy_block_syms_iternext,	  /*tp_iternext */
547   block_iterator_object_methods   /*tp_methods */
548 };
549