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