]> Git Repo - binutils.git/blob - gdb/python/py-block.c
Normalize include guards in gdb
[binutils.git] / gdb / python / py-block.c
1 /* Python interface to blocks.
2
3    Copyright (C) 2008-2019 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
27 typedef struct blpy_block_object {
28   PyObject_HEAD
29   /* The GDB block structure that represents a frame's code block.  */
30   const struct block *block;
31   /* The backing object file.  There is no direct relationship in GDB
32      between a block and an object file.  When a block is created also
33      store a pointer to the object file for later use.  */
34   struct objfile *objfile;
35   /* Keep track of all blocks with a doubly-linked list.  Needed for
36      block invalidation if the source object file has been freed.  */
37   struct blpy_block_object *prev;
38   struct blpy_block_object *next;
39 } block_object;
40
41 typedef struct {
42   PyObject_HEAD
43   /* The block.  */
44   const struct block *block;
45   /* The iterator for that block.  */
46   struct block_iterator iter;
47   /* Has the iterator been initialized flag.  */
48   int initialized_p;
49   /* Pointer back to the original source block object.  Needed to
50      check if the block is still valid, and has not been invalidated
51      when an object file has been freed.  */
52   struct blpy_block_object *source;
53 } block_syms_iterator_object;
54
55 /* Require a valid block.  All access to block_object->block should be
56    gated by this call.  */
57 #define BLPY_REQUIRE_VALID(block_obj, block)            \
58   do {                                                  \
59     block = block_object_to_block (block_obj);          \
60     if (block == NULL)                                  \
61       {                                                 \
62         PyErr_SetString (PyExc_RuntimeError,            \
63                          _("Block is invalid."));       \
64         return NULL;                                    \
65       }                                                 \
66   } while (0)
67
68 /* Require a valid block.  This macro is called during block iterator
69    creation, and at each next call.  */
70 #define BLPY_ITER_REQUIRE_VALID(block_obj)                              \
71   do {                                                                  \
72     if (block_obj->block == NULL)                                       \
73       {                                                                 \
74         PyErr_SetString (PyExc_RuntimeError,                            \
75                          _("Source block for iterator is invalid."));   \
76         return NULL;                                                    \
77       }                                                                 \
78   } while (0)
79
80 extern PyTypeObject block_syms_iterator_object_type
81     CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("block_syms_iterator_object");
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   const 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->block = 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   const struct block *block = NULL;
109
110   BLPY_REQUIRE_VALID (self, block);
111
112   return gdb_py_object_from_ulongest (BLOCK_START (block)).release ();
113 }
114
115 static PyObject *
116 blpy_get_end (PyObject *self, void *closure)
117 {
118   const struct block *block = NULL;
119
120   BLPY_REQUIRE_VALID (self, block);
121
122   return gdb_py_object_from_ulongest (BLOCK_END (block)).release ();
123 }
124
125 static PyObject *
126 blpy_get_function (PyObject *self, void *closure)
127 {
128   struct symbol *sym;
129   const struct block *block;
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   const struct block *block;
144   const struct block *super_block;
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 /* Return the global block associated to this block.  */
157
158 static PyObject *
159 blpy_get_global_block (PyObject *self, void *closure)
160 {
161   const struct block *block;
162   const struct block *global_block;
163   block_object *self_obj  = (block_object *) self;
164
165   BLPY_REQUIRE_VALID (self, block);
166
167   global_block = block_global_block (block);
168
169   return block_to_block_object (global_block,
170                                 self_obj->objfile);
171
172 }
173
174 /* Return the static block associated to this block.  Return None
175    if we cannot get the static block (this is the global block).  */
176
177 static PyObject *
178 blpy_get_static_block (PyObject *self, void *closure)
179 {
180   const struct block *block;
181   const struct block *static_block;
182   block_object *self_obj  = (block_object *) self;
183
184   BLPY_REQUIRE_VALID (self, block);
185
186   if (BLOCK_SUPERBLOCK (block) == NULL)
187     Py_RETURN_NONE;
188
189   static_block = block_static_block (block);
190
191   return block_to_block_object (static_block, self_obj->objfile);
192 }
193
194 /* Implementation of gdb.Block.is_global (self) -> Boolean.
195    Returns True if this block object is a global block.  */
196
197 static PyObject *
198 blpy_is_global (PyObject *self, void *closure)
199 {
200   const struct block *block;
201
202   BLPY_REQUIRE_VALID (self, block);
203
204   if (BLOCK_SUPERBLOCK (block))
205     Py_RETURN_FALSE;
206
207   Py_RETURN_TRUE;
208 }
209
210 /* Implementation of gdb.Block.is_static (self) -> Boolean.
211    Returns True if this block object is a static block.  */
212
213 static PyObject *
214 blpy_is_static (PyObject *self, void *closure)
215 {
216   const struct block *block;
217
218   BLPY_REQUIRE_VALID (self, block);
219
220   if (BLOCK_SUPERBLOCK (block) != NULL
221      && BLOCK_SUPERBLOCK (BLOCK_SUPERBLOCK (block)) == NULL)
222     Py_RETURN_TRUE;
223
224   Py_RETURN_FALSE;
225 }
226
227 static void
228 blpy_dealloc (PyObject *obj)
229 {
230   block_object *block = (block_object *) obj;
231
232   if (block->prev)
233     block->prev->next = block->next;
234   else if (block->objfile)
235     {
236       set_objfile_data (block->objfile, blpy_objfile_data_key,
237                         block->next);
238     }
239   if (block->next)
240     block->next->prev = block->prev;
241   block->block = NULL;
242 }
243
244 /* Given a block, and a block_object that has previously been
245    allocated and initialized, populate the block_object with the
246    struct block data.  Also, register the block_object life-cycle
247    with the life-cycle of the object file associated with this
248    block, if needed.  */
249 static void
250 set_block (block_object *obj, const struct block *block,
251            struct objfile *objfile)
252 {
253   obj->block = block;
254   obj->prev = NULL;
255   if (objfile)
256     {
257       obj->objfile = objfile;
258       obj->next = ((struct blpy_block_object *)
259                    objfile_data (objfile, blpy_objfile_data_key));
260       if (obj->next)
261         obj->next->prev = obj;
262       set_objfile_data (objfile, blpy_objfile_data_key, obj);
263     }
264   else
265     obj->next = NULL;
266 }
267
268 /* Create a new block object (gdb.Block) that encapsulates the struct
269    block object from GDB.  */
270 PyObject *
271 block_to_block_object (const struct block *block, struct objfile *objfile)
272 {
273   block_object *block_obj;
274
275   block_obj = PyObject_New (block_object, &block_object_type);
276   if (block_obj)
277     set_block (block_obj, block, objfile);
278
279   return (PyObject *) block_obj;
280 }
281
282 /* Return struct block reference that is wrapped by this object.  */
283 const struct block *
284 block_object_to_block (PyObject *obj)
285 {
286   if (! PyObject_TypeCheck (obj, &block_object_type))
287     return NULL;
288   return ((block_object *) obj)->block;
289 }
290
291 /* Return a reference to the block iterator.  */
292 static PyObject *
293 blpy_block_syms_iter (PyObject *self)
294 {
295   block_syms_iterator_object *iter_obj = (block_syms_iterator_object *) self;
296
297   BLPY_ITER_REQUIRE_VALID (iter_obj->source);
298
299   Py_INCREF (self);
300   return self;
301 }
302
303 /* Return the next symbol in the iteration through the block's
304    dictionary.  */
305 static PyObject *
306 blpy_block_syms_iternext (PyObject *self)
307 {
308   block_syms_iterator_object *iter_obj = (block_syms_iterator_object *) self;
309   struct symbol *sym;
310
311   BLPY_ITER_REQUIRE_VALID (iter_obj->source);
312
313   if (!iter_obj->initialized_p)
314     {
315       sym = block_iterator_first (iter_obj->block,  &(iter_obj->iter));
316       iter_obj->initialized_p = 1;
317     }
318   else
319     sym = block_iterator_next (&(iter_obj->iter));
320
321   if (sym == NULL)
322     {
323       PyErr_SetString (PyExc_StopIteration, _("Symbol is null."));
324       return NULL;
325     }
326
327   return symbol_to_symbol_object (sym);
328 }
329
330 static void
331 blpy_block_syms_dealloc (PyObject *obj)
332 {
333   block_syms_iterator_object *iter_obj = (block_syms_iterator_object *) obj;
334
335   Py_XDECREF (iter_obj->source);
336 }
337
338 /* Implementation of gdb.Block.is_valid (self) -> Boolean.
339    Returns True if this block object still exists in GDB.  */
340
341 static PyObject *
342 blpy_is_valid (PyObject *self, PyObject *args)
343 {
344   const struct block *block;
345
346   block = block_object_to_block (self);
347   if (block == NULL)
348     Py_RETURN_FALSE;
349
350   Py_RETURN_TRUE;
351 }
352
353 /* Implementation of gdb.BlockIterator.is_valid (self) -> Boolean.
354    Returns True if this block iterator object still exists in GDB  */
355
356 static PyObject *
357 blpy_iter_is_valid (PyObject *self, PyObject *args)
358 {
359   block_syms_iterator_object *iter_obj =
360     (block_syms_iterator_object *) self;
361
362   if (iter_obj->source->block == NULL)
363     Py_RETURN_FALSE;
364
365   Py_RETURN_TRUE;
366 }
367
368 /* This function is called when an objfile is about to be freed.
369    Invalidate the block as further actions on the block would result
370    in bad data.  All access to obj->symbol should be gated by
371    BLPY_REQUIRE_VALID which will raise an exception on invalid
372    blocks.  */
373 static void
374 del_objfile_blocks (struct objfile *objfile, void *datum)
375 {
376   block_object *obj = (block_object *) datum;
377
378   while (obj)
379     {
380       block_object *next = obj->next;
381
382       obj->block = NULL;
383       obj->objfile = NULL;
384       obj->next = NULL;
385       obj->prev = NULL;
386
387       obj = next;
388     }
389 }
390
391 int
392 gdbpy_initialize_blocks (void)
393 {
394   block_object_type.tp_new = PyType_GenericNew;
395   if (PyType_Ready (&block_object_type) < 0)
396     return -1;
397
398   block_syms_iterator_object_type.tp_new = PyType_GenericNew;
399   if (PyType_Ready (&block_syms_iterator_object_type) < 0)
400     return -1;
401
402   /* Register an objfile "free" callback so we can properly
403      invalidate blocks when an object file is about to be
404      deleted.  */
405   blpy_objfile_data_key
406     = register_objfile_data_with_cleanup (NULL, del_objfile_blocks);
407
408   if (gdb_pymodule_addobject (gdb_module, "Block",
409                               (PyObject *) &block_object_type) < 0)
410     return -1;
411
412   return gdb_pymodule_addobject (gdb_module, "BlockIterator",
413                                  (PyObject *) &block_syms_iterator_object_type);
414 }
415
416 \f
417
418 static PyMethodDef block_object_methods[] = {
419   { "is_valid", blpy_is_valid, METH_NOARGS,
420     "is_valid () -> Boolean.\n\
421 Return true if this block is valid, false if not." },
422   {NULL}  /* Sentinel */
423 };
424
425 static gdb_PyGetSetDef block_object_getset[] = {
426   { "start", blpy_get_start, NULL, "Start address of the block.", NULL },
427   { "end", blpy_get_end, NULL, "End address of the block.", NULL },
428   { "function", blpy_get_function, NULL,
429     "Symbol that names the block, or None.", NULL },
430   { "superblock", blpy_get_superblock, NULL,
431     "Block containing the block, or None.", NULL },
432   { "global_block", blpy_get_global_block, NULL,
433     "Block containing the global block.", NULL },
434   { "static_block", blpy_get_static_block, NULL,
435     "Block containing the static block.", NULL },
436   { "is_static", blpy_is_static, NULL,
437     "Whether this block is a static block.", NULL },
438   { "is_global", blpy_is_global, NULL,
439     "Whether this block is a global block.", NULL },
440   { NULL }  /* Sentinel */
441 };
442
443 PyTypeObject block_object_type = {
444   PyVarObject_HEAD_INIT (NULL, 0)
445   "gdb.Block",                    /*tp_name*/
446   sizeof (block_object),          /*tp_basicsize*/
447   0,                              /*tp_itemsize*/
448   blpy_dealloc,                   /*tp_dealloc*/
449   0,                              /*tp_print*/
450   0,                              /*tp_getattr*/
451   0,                              /*tp_setattr*/
452   0,                              /*tp_compare*/
453   0,                              /*tp_repr*/
454   0,                              /*tp_as_number*/
455   0,                              /*tp_as_sequence*/
456   0,                              /*tp_as_mapping*/
457   0,                              /*tp_hash */
458   0,                              /*tp_call*/
459   0,                              /*tp_str*/
460   0,                              /*tp_getattro*/
461   0,                              /*tp_setattro*/
462   0,                              /*tp_as_buffer*/
463   Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_ITER,  /*tp_flags*/
464   "GDB block object",             /* tp_doc */
465   0,                              /* tp_traverse */
466   0,                              /* tp_clear */
467   0,                              /* tp_richcompare */
468   0,                              /* tp_weaklistoffset */
469   blpy_iter,                      /* tp_iter */
470   0,                              /* tp_iternext */
471   block_object_methods,           /* tp_methods */
472   0,                              /* tp_members */
473   block_object_getset             /* tp_getset */
474 };
475
476 static PyMethodDef block_iterator_object_methods[] = {
477   { "is_valid", blpy_iter_is_valid, METH_NOARGS,
478     "is_valid () -> Boolean.\n\
479 Return true if this block iterator is valid, false if not." },
480   {NULL}  /* Sentinel */
481 };
482
483 PyTypeObject block_syms_iterator_object_type = {
484   PyVarObject_HEAD_INIT (NULL, 0)
485   "gdb.BlockIterator",            /*tp_name*/
486   sizeof (block_syms_iterator_object),        /*tp_basicsize*/
487   0,                              /*tp_itemsize*/
488   blpy_block_syms_dealloc,        /*tp_dealloc*/
489   0,                              /*tp_print*/
490   0,                              /*tp_getattr*/
491   0,                              /*tp_setattr*/
492   0,                              /*tp_compare*/
493   0,                              /*tp_repr*/
494   0,                              /*tp_as_number*/
495   0,                              /*tp_as_sequence*/
496   0,                              /*tp_as_mapping*/
497   0,                              /*tp_hash */
498   0,                              /*tp_call*/
499   0,                              /*tp_str*/
500   0,                              /*tp_getattro*/
501   0,                              /*tp_setattro*/
502   0,                              /*tp_as_buffer*/
503   Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_ITER,  /*tp_flags*/
504   "GDB block syms iterator object",           /*tp_doc */
505   0,                              /*tp_traverse */
506   0,                              /*tp_clear */
507   0,                              /*tp_richcompare */
508   0,                              /*tp_weaklistoffset */
509   blpy_block_syms_iter,           /*tp_iter */
510   blpy_block_syms_iternext,       /*tp_iternext */
511   block_iterator_object_methods   /*tp_methods */
512 };
This page took 0.057156 seconds and 4 git commands to generate.