xref: /dragonfly/contrib/gdb-7/gdb/python/py-block.c (revision 6e278935)
1 /* Python interface to blocks.
2 
3    Copyright (C) 2008, 2009, 2010, 2011 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   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 dictionary of symbols.  */
45   struct dictionary *dict;
46   /* The iterator for that dictionary.  */
47   struct dict_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   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->dict = BLOCK_DICT (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   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   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   struct block *block = NULL;
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   struct block *block = NULL;
144   struct block *super_block = NULL;
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 static void
157 blpy_dealloc (PyObject *obj)
158 {
159   block_object *block = (block_object *) obj;
160 
161   if (block->prev)
162     block->prev->next = block->next;
163   else if (block->objfile)
164     {
165       set_objfile_data (block->objfile, blpy_objfile_data_key,
166 			block->next);
167     }
168   if (block->next)
169     block->next->prev = block->prev;
170   block->block = NULL;
171 }
172 
173 /* Given a block, and a block_object that has previously been
174    allocated and initialized, populate the block_object with the
175    struct block data.  Also, register the block_object life-cycle
176    with the life-cycle of the object file associated with this
177    block, if needed.  */
178 static void
179 set_block (block_object *obj, struct block *block,
180 	   struct objfile *objfile)
181 {
182   obj->block = block;
183   obj->prev = NULL;
184   if (objfile)
185     {
186       obj->objfile = objfile;
187       obj->next = objfile_data (objfile, blpy_objfile_data_key);
188       if (obj->next)
189 	obj->next->prev = obj;
190       set_objfile_data (objfile, blpy_objfile_data_key, obj);
191     }
192   else
193     obj->next = NULL;
194 }
195 
196 /* Create a new block object (gdb.Block) that encapsulates the struct
197    block object from GDB.  */
198 PyObject *
199 block_to_block_object (struct block *block, struct objfile *objfile)
200 {
201   block_object *block_obj;
202 
203   block_obj = PyObject_New (block_object, &block_object_type);
204   if (block_obj)
205     set_block (block_obj, block, objfile);
206 
207   return (PyObject *) block_obj;
208 }
209 
210 /* Return struct block reference that is wrapped by this object.  */
211 struct block *
212 block_object_to_block (PyObject *obj)
213 {
214   if (! PyObject_TypeCheck (obj, &block_object_type))
215     return NULL;
216   return ((block_object *) obj)->block;
217 }
218 
219 /* Return a reference to the block iterator.  */
220 static PyObject *
221 blpy_block_syms_iter (PyObject *self)
222 {
223   block_syms_iterator_object *iter_obj = (block_syms_iterator_object *) self;
224 
225   BLPY_ITER_REQUIRE_VALID (iter_obj->source);
226 
227   Py_INCREF (self);
228   return self;
229 }
230 
231 /* Return the next symbol in the iteration through the block's
232    dictionary.  */
233 static PyObject *
234 blpy_block_syms_iternext (PyObject *self)
235 {
236   block_syms_iterator_object *iter_obj = (block_syms_iterator_object *) self;
237   struct symbol *sym;
238 
239   BLPY_ITER_REQUIRE_VALID (iter_obj->source);
240 
241   if (!iter_obj->initialized_p)
242     {
243       sym = dict_iterator_first (iter_obj->dict,  &(iter_obj->iter));
244       iter_obj->initialized_p = 1;
245     }
246   else
247     sym = dict_iterator_next (&(iter_obj->iter));
248 
249   if (sym == NULL)
250     {
251       PyErr_SetString (PyExc_StopIteration, _("Symbol is null."));
252       return NULL;
253     }
254 
255   return symbol_to_symbol_object (sym);
256 }
257 
258 static void
259 blpy_block_syms_dealloc (PyObject *obj)
260 {
261   block_syms_iterator_object *iter_obj = (block_syms_iterator_object *) obj;
262 
263   Py_XDECREF (iter_obj->source);
264 }
265 
266 /* Implementation of gdb.Block.is_valid (self) -> Boolean.
267    Returns True if this block object still exists in GDB.  */
268 
269 static PyObject *
270 blpy_is_valid (PyObject *self, PyObject *args)
271 {
272   struct block *block;
273 
274   block = block_object_to_block (self);
275   if (block == NULL)
276     Py_RETURN_FALSE;
277 
278   Py_RETURN_TRUE;
279 }
280 
281 /* Implementation of gdb.BlockIterator.is_valid (self) -> Boolean.
282    Returns True if this block iterator object still exists in GDB  */
283 
284 static PyObject *
285 blpy_iter_is_valid (PyObject *self, PyObject *args)
286 {
287   block_syms_iterator_object *iter_obj =
288     (block_syms_iterator_object *) self;
289 
290   if (iter_obj->source->block == NULL)
291     Py_RETURN_FALSE;
292 
293   Py_RETURN_TRUE;
294 }
295 
296 /* Return the innermost lexical block containing the specified pc value,
297    or 0 if there is none.  */
298 PyObject *
299 gdbpy_block_for_pc (PyObject *self, PyObject *args)
300 {
301   gdb_py_ulongest pc;
302   struct block *block;
303   struct obj_section *section;
304   struct symtab *symtab;
305 
306   if (!PyArg_ParseTuple (args, GDB_PY_LLU_ARG, &pc))
307     return NULL;
308 
309   section = find_pc_mapped_section (pc);
310   symtab = find_pc_sect_symtab (pc, section);
311   if (!symtab || symtab->objfile == NULL)
312     {
313       PyErr_SetString (PyExc_RuntimeError,
314 		       _("Cannot locate object file for block."));
315       return NULL;
316     }
317 
318   block = block_for_pc (pc);
319   if (block)
320     return block_to_block_object (block, symtab->objfile);
321 
322   Py_RETURN_NONE;
323 }
324 
325 /* This function is called when an objfile is about to be freed.
326    Invalidate the block as further actions on the block would result
327    in bad data.  All access to obj->symbol should be gated by
328    BLPY_REQUIRE_VALID which will raise an exception on invalid
329    blocks.  */
330 static void
331 del_objfile_blocks (struct objfile *objfile, void *datum)
332 {
333   block_object *obj = datum;
334 
335   while (obj)
336     {
337       block_object *next = obj->next;
338 
339       obj->block = NULL;
340       obj->objfile = NULL;
341       obj->next = NULL;
342       obj->prev = NULL;
343 
344       obj = next;
345     }
346 }
347 
348 void
349 gdbpy_initialize_blocks (void)
350 {
351   block_object_type.tp_new = PyType_GenericNew;
352   if (PyType_Ready (&block_object_type) < 0)
353     return;
354 
355   block_syms_iterator_object_type.tp_new = PyType_GenericNew;
356   if (PyType_Ready (&block_syms_iterator_object_type) < 0)
357     return;
358 
359   /* Register an objfile "free" callback so we can properly
360      invalidate blocks when an object file is about to be
361      deleted.  */
362   blpy_objfile_data_key
363     = register_objfile_data_with_cleanup (NULL, del_objfile_blocks);
364 
365   Py_INCREF (&block_object_type);
366   PyModule_AddObject (gdb_module, "Block", (PyObject *) &block_object_type);
367 
368   Py_INCREF (&block_syms_iterator_object_type);
369   PyModule_AddObject (gdb_module, "BlockIterator",
370 		      (PyObject *) &block_syms_iterator_object_type);
371 }
372 
373 
374 
375 static PyMethodDef block_object_methods[] = {
376   { "is_valid", blpy_is_valid, METH_NOARGS,
377     "is_valid () -> Boolean.\n\
378 Return true if this block is valid, false if not." },
379   {NULL}  /* Sentinel */
380 };
381 
382 static PyGetSetDef block_object_getset[] = {
383   { "start", blpy_get_start, NULL, "Start address of the block.", NULL },
384   { "end", blpy_get_end, NULL, "End address of the block.", NULL },
385   { "function", blpy_get_function, NULL,
386     "Symbol that names the block, or None.", NULL },
387   { "superblock", blpy_get_superblock, NULL,
388     "Block containing the block, or None.", NULL },
389   { NULL }  /* Sentinel */
390 };
391 
392 PyTypeObject block_object_type = {
393   PyObject_HEAD_INIT (NULL)
394   0,				  /*ob_size*/
395   "gdb.Block",			  /*tp_name*/
396   sizeof (block_object),	  /*tp_basicsize*/
397   0,				  /*tp_itemsize*/
398   blpy_dealloc,                   /*tp_dealloc*/
399   0,				  /*tp_print*/
400   0,				  /*tp_getattr*/
401   0,				  /*tp_setattr*/
402   0,				  /*tp_compare*/
403   0,				  /*tp_repr*/
404   0,				  /*tp_as_number*/
405   0,				  /*tp_as_sequence*/
406   0,				  /*tp_as_mapping*/
407   0,				  /*tp_hash */
408   0,				  /*tp_call*/
409   0,				  /*tp_str*/
410   0,				  /*tp_getattro*/
411   0,				  /*tp_setattro*/
412   0,				  /*tp_as_buffer*/
413   Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_ITER,  /*tp_flags*/
414   "GDB block object",		  /* tp_doc */
415   0,				  /* tp_traverse */
416   0,				  /* tp_clear */
417   0,				  /* tp_richcompare */
418   0,				  /* tp_weaklistoffset */
419   blpy_iter,			  /* tp_iter */
420   0,				  /* tp_iternext */
421   block_object_methods,		  /* tp_methods */
422   0,				  /* tp_members */
423   block_object_getset		  /* tp_getset */
424 };
425 
426 static PyMethodDef block_iterator_object_methods[] = {
427   { "is_valid", blpy_iter_is_valid, METH_NOARGS,
428     "is_valid () -> Boolean.\n\
429 Return true if this block iterator is valid, false if not." },
430   {NULL}  /* Sentinel */
431 };
432 
433 static PyTypeObject block_syms_iterator_object_type = {
434   PyObject_HEAD_INIT (NULL)
435   0,				  /*ob_size*/
436   "gdb.BlockIterator",		  /*tp_name*/
437   sizeof (block_syms_iterator_object),	      /*tp_basicsize*/
438   0,				  /*tp_itemsize*/
439   blpy_block_syms_dealloc,	  /*tp_dealloc*/
440   0,				  /*tp_print*/
441   0,				  /*tp_getattr*/
442   0,				  /*tp_setattr*/
443   0,				  /*tp_compare*/
444   0,				  /*tp_repr*/
445   0,				  /*tp_as_number*/
446   0,				  /*tp_as_sequence*/
447   0,				  /*tp_as_mapping*/
448   0,				  /*tp_hash */
449   0,				  /*tp_call*/
450   0,				  /*tp_str*/
451   0,				  /*tp_getattro*/
452   0,				  /*tp_setattro*/
453   0,				  /*tp_as_buffer*/
454   Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_ITER,  /*tp_flags*/
455   "GDB block syms iterator object",	      /*tp_doc */
456   0,				  /*tp_traverse */
457   0,				  /*tp_clear */
458   0,				  /*tp_richcompare */
459   0,				  /*tp_weaklistoffset */
460   blpy_block_syms_iter,           /*tp_iter */
461   blpy_block_syms_iternext,	  /*tp_iternext */
462   block_iterator_object_methods   /*tp_methods */
463 };
464