Upload Tizen:Base source
[external/gdb.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
263   Py_XDECREF (iter_obj->source);
264 }
265
266 /* Return the innermost lexical block containing the specified pc value,
267    or 0 if there is none.  */
268 PyObject *
269 gdbpy_block_for_pc (PyObject *self, PyObject *args)
270 {
271   unsigned PY_LONG_LONG pc;
272   struct block *block;
273   struct obj_section *section;
274   struct symtab *symtab;
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
305   while (obj)
306     {
307       block_object *next = obj->next;
308
309       obj->block = NULL;
310       obj->objfile = NULL;
311       obj->next = NULL;
312       obj->prev = NULL;
313
314       obj = next;
315     }
316 }
317
318 void
319 gdbpy_initialize_blocks (void)
320 {
321   block_object_type.tp_new = PyType_GenericNew;
322   if (PyType_Ready (&block_object_type) < 0)
323     return;
324
325   block_syms_iterator_object_type.tp_new = PyType_GenericNew;
326   if (PyType_Ready (&block_syms_iterator_object_type) < 0)
327     return;
328
329   /* Register an objfile "free" callback so we can properly
330      invalidate blocks when an object file is about to be
331      deleted.  */
332   blpy_objfile_data_key
333     = register_objfile_data_with_cleanup (NULL, del_objfile_blocks);
334
335   Py_INCREF (&block_object_type);
336   PyModule_AddObject (gdb_module, "Block", (PyObject *) &block_object_type);
337
338   Py_INCREF (&block_syms_iterator_object_type);
339   PyModule_AddObject (gdb_module, "BlockIterator",
340                       (PyObject *) &block_syms_iterator_object_type);
341 }
342
343 \f
344
345 static PyGetSetDef block_object_getset[] = {
346   { "start", blpy_get_start, NULL, "Start address of the block.", NULL },
347   { "end", blpy_get_end, NULL, "End address of the block.", NULL },
348   { "function", blpy_get_function, NULL,
349     "Symbol that names the block, or None.", NULL },
350   { "superblock", blpy_get_superblock, NULL,
351     "Block containing the block, or None.", NULL },
352   { NULL }  /* Sentinel */
353 };
354
355 PyTypeObject block_object_type = {
356   PyObject_HEAD_INIT (NULL)
357   0,                              /*ob_size*/
358   "gdb.Block",                    /*tp_name*/
359   sizeof (block_object),          /*tp_basicsize*/
360   0,                              /*tp_itemsize*/
361   blpy_dealloc,                   /*tp_dealloc*/
362   0,                              /*tp_print*/
363   0,                              /*tp_getattr*/
364   0,                              /*tp_setattr*/
365   0,                              /*tp_compare*/
366   0,                              /*tp_repr*/
367   0,                              /*tp_as_number*/
368   0,                              /*tp_as_sequence*/
369   0,                              /*tp_as_mapping*/
370   0,                              /*tp_hash */
371   0,                              /*tp_call*/
372   0,                              /*tp_str*/
373   0,                              /*tp_getattro*/
374   0,                              /*tp_setattro*/
375   0,                              /*tp_as_buffer*/
376   Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_ITER,  /*tp_flags*/
377   "GDB block object",             /* tp_doc */
378   0,                              /* tp_traverse */
379   0,                              /* tp_clear */
380   0,                              /* tp_richcompare */
381   0,                              /* tp_weaklistoffset */
382   blpy_iter,                      /* tp_iter */
383   0,                              /* tp_iternext */
384   0,                              /* tp_methods */
385   0,                              /* tp_members */
386   block_object_getset             /* tp_getset */
387 };
388
389 static PyTypeObject block_syms_iterator_object_type = {
390   PyObject_HEAD_INIT (NULL)
391   0,                              /*ob_size*/
392   "gdb.BlockIterator",            /*tp_name*/
393   sizeof (block_syms_iterator_object),        /*tp_basicsize*/
394   0,                              /*tp_itemsize*/
395   blpy_block_syms_dealloc,        /*tp_dealloc*/
396   0,                              /*tp_print*/
397   0,                              /*tp_getattr*/
398   0,                              /*tp_setattr*/
399   0,                              /*tp_compare*/
400   0,                              /*tp_repr*/
401   0,                              /*tp_as_number*/
402   0,                              /*tp_as_sequence*/
403   0,                              /*tp_as_mapping*/
404   0,                              /*tp_hash */
405   0,                              /*tp_call*/
406   0,                              /*tp_str*/
407   0,                              /*tp_getattro*/
408   0,                              /*tp_setattro*/
409   0,                              /*tp_as_buffer*/
410   Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_ITER,  /*tp_flags*/
411   "GDB block syms iterator object",           /*tp_doc */
412   0,                              /*tp_traverse */
413   0,                              /*tp_clear */
414   0,                              /*tp_richcompare */
415   0,                              /*tp_weaklistoffset */
416   blpy_block_syms_iter,           /*tp_iter */
417   blpy_block_syms_iternext,       /*tp_iternext */
418   0                               /*tp_methods */
419 };