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