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