daily update
[external/binutils.git] / gdb / python / py-block.c
1 /* Python interface to blocks.
2
3    Copyright (C) 2008, 2009, 2010 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 PyLong_FromUnsignedLongLong (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 PyLong_FromUnsignedLongLong (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 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   Py_XDECREF (iter_obj->source);
263 }
264
265 /* Return the innermost lexical block containing the specified pc value,
266    or 0 if there is none.  */
267 PyObject *
268 gdbpy_block_for_pc (PyObject *self, PyObject *args)
269 {
270   unsigned PY_LONG_LONG pc;
271   struct block *block;
272   struct obj_section *section;
273   struct symtab *symtab;
274   PyObject *sym_obj;
275
276   if (!PyArg_ParseTuple (args, "K", &pc))
277     return NULL;
278
279   section = find_pc_mapped_section (pc);
280   symtab = find_pc_sect_symtab (pc, section);
281   if (!symtab || symtab->objfile == NULL)
282     {
283       PyErr_SetString (PyExc_RuntimeError,
284                        _("Cannot locate object file for block."));
285       return NULL;
286     }
287
288   block = block_for_pc (pc);
289   if (block)
290     return block_to_block_object (block, symtab->objfile);
291
292   Py_RETURN_NONE;
293 }
294
295 /* This function is called when an objfile is about to be freed.
296    Invalidate the block as further actions on the block would result
297    in bad data.  All access to obj->symbol should be gated by
298    BLPY_REQUIRE_VALID which will raise an exception on invalid
299    blocks.  */
300 static void
301 del_objfile_blocks (struct objfile *objfile, void *datum)
302 {
303   block_object *obj = datum;
304   while (obj)
305     {
306       block_object *next = obj->next;
307
308       obj->block = NULL;
309       obj->objfile = NULL;
310       obj->next = NULL;
311       obj->prev = NULL;
312
313       obj = next;
314     }
315 }
316
317 void
318 gdbpy_initialize_blocks (void)
319 {
320   block_object_type.tp_new = PyType_GenericNew;
321   if (PyType_Ready (&block_object_type) < 0)
322     return;
323
324   block_syms_iterator_object_type.tp_new = PyType_GenericNew;
325   if (PyType_Ready (&block_syms_iterator_object_type) < 0)
326     return;
327
328   /* Register an objfile "free" callback so we can properly
329      invalidate blocks when an object file is about to be
330      deleted.  */
331   blpy_objfile_data_key
332     = register_objfile_data_with_cleanup (NULL, del_objfile_blocks);
333
334   Py_INCREF (&block_object_type);
335   PyModule_AddObject (gdb_module, "Block", (PyObject *) &block_object_type);
336
337   Py_INCREF (&block_syms_iterator_object_type);
338   PyModule_AddObject (gdb_module, "BlockIterator",
339                       (PyObject *) &block_syms_iterator_object_type);
340 }
341
342 \f
343
344 static PyGetSetDef block_object_getset[] = {
345   { "start", blpy_get_start, NULL, "Start address of the block.", NULL },
346   { "end", blpy_get_end, NULL, "End address of the block.", NULL },
347   { "function", blpy_get_function, NULL,
348     "Symbol that names the block, or None.", NULL },
349   { "superblock", blpy_get_superblock, NULL,
350     "Block containing the block, or None.", NULL },
351   { NULL }  /* Sentinel */
352 };
353
354 PyTypeObject block_object_type = {
355   PyObject_HEAD_INIT (NULL)
356   0,                              /*ob_size*/
357   "gdb.Block",                    /*tp_name*/
358   sizeof (block_object),          /*tp_basicsize*/
359   0,                              /*tp_itemsize*/
360   blpy_dealloc,                   /*tp_dealloc*/
361   0,                              /*tp_print*/
362   0,                              /*tp_getattr*/
363   0,                              /*tp_setattr*/
364   0,                              /*tp_compare*/
365   0,                              /*tp_repr*/
366   0,                              /*tp_as_number*/
367   0,                              /*tp_as_sequence*/
368   0,                              /*tp_as_mapping*/
369   0,                              /*tp_hash */
370   0,                              /*tp_call*/
371   0,                              /*tp_str*/
372   0,                              /*tp_getattro*/
373   0,                              /*tp_setattro*/
374   0,                              /*tp_as_buffer*/
375   Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_ITER,  /*tp_flags*/
376   "GDB block object",             /* tp_doc */
377   0,                              /* tp_traverse */
378   0,                              /* tp_clear */
379   0,                              /* tp_richcompare */
380   0,                              /* tp_weaklistoffset */
381   blpy_iter,                      /* tp_iter */
382   0,                              /* tp_iternext */
383   0,                              /* tp_methods */
384   0,                              /* tp_members */
385   block_object_getset             /* tp_getset */
386 };
387
388 static PyTypeObject block_syms_iterator_object_type = {
389   PyObject_HEAD_INIT (NULL)
390   0,                              /*ob_size*/
391   "gdb.BlockIterator",            /*tp_name*/
392   sizeof (block_syms_iterator_object),        /*tp_basicsize*/
393   0,                              /*tp_itemsize*/
394   blpy_block_syms_dealloc,        /*tp_dealloc*/
395   0,                              /*tp_print*/
396   0,                              /*tp_getattr*/
397   0,                              /*tp_setattr*/
398   0,                              /*tp_compare*/
399   0,                              /*tp_repr*/
400   0,                              /*tp_as_number*/
401   0,                              /*tp_as_sequence*/
402   0,                              /*tp_as_mapping*/
403   0,                              /*tp_hash */
404   0,                              /*tp_call*/
405   0,                              /*tp_str*/
406   0,                              /*tp_getattro*/
407   0,                              /*tp_setattro*/
408   0,                              /*tp_as_buffer*/
409   Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_ITER,  /*tp_flags*/
410   "GDB block syms iterator object",           /*tp_doc */
411   0,                              /*tp_traverse */
412   0,                              /*tp_clear */
413   0,                              /*tp_richcompare */
414   0,                              /*tp_weaklistoffset */
415   blpy_block_syms_iter,           /*tp_iter */
416   blpy_block_syms_iternext,       /*tp_iternext */
417   0                               /*tp_methods */
418 };