GDB (API)
/home/stan/gdb/src/gdb/python/py-block.c
Go to the documentation of this file.
00001 /* Python interface to blocks.
00002 
00003    Copyright (C) 2008-2013 Free Software Foundation, Inc.
00004 
00005    This file is part of GDB.
00006 
00007    This program is free software; you can redistribute it and/or modify
00008    it under the terms of the GNU General Public License as published by
00009    the Free Software Foundation; either version 3 of the License, or
00010    (at your option) any later version.
00011 
00012    This program is distributed in the hope that it will be useful,
00013    but WITHOUT ANY WARRANTY; without even the implied warranty of
00014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015    GNU General Public License for more details.
00016 
00017    You should have received a copy of the GNU General Public License
00018    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
00019 
00020 #include "defs.h"
00021 #include "block.h"
00022 #include "dictionary.h"
00023 #include "symtab.h"
00024 #include "python-internal.h"
00025 #include "objfiles.h"
00026 #include "symtab.h"
00027 
00028 typedef struct blpy_block_object {
00029   PyObject_HEAD
00030   /* The GDB block structure that represents a frame's code block.  */
00031   const struct block *block;
00032   /* The backing object file.  There is no direct relationship in GDB
00033      between a block and an object file.  When a block is created also
00034      store a pointer to the object file for later use.  */
00035   struct objfile *objfile;
00036   /* Keep track of all blocks with a doubly-linked list.  Needed for
00037      block invalidation if the source object file has been freed.  */
00038   struct blpy_block_object *prev;
00039   struct blpy_block_object *next;
00040 } block_object;
00041 
00042 typedef struct {
00043   PyObject_HEAD
00044   /* The block.  */
00045   const struct block *block;
00046   /* The iterator for that block.  */
00047   struct block_iterator iter;
00048   /* Has the iterator been initialized flag.  */
00049   int initialized_p;
00050   /* Pointer back to the original source block object.  Needed to
00051      check if the block is still valid, and has not been invalidated
00052      when an object file has been freed.  */
00053   struct blpy_block_object *source;
00054 } block_syms_iterator_object;
00055 
00056 /* Require a valid block.  All access to block_object->block should be
00057    gated by this call.  */
00058 #define BLPY_REQUIRE_VALID(block_obj, block)            \
00059   do {                                                  \
00060     block = block_object_to_block (block_obj);          \
00061     if (block == NULL)                                  \
00062       {                                                 \
00063         PyErr_SetString (PyExc_RuntimeError,            \
00064                          _("Block is invalid."));       \
00065         return NULL;                                    \
00066       }                                                 \
00067   } while (0)
00068 
00069 /* Require a valid block.  This macro is called during block iterator
00070    creation, and at each next call.  */
00071 #define BLPY_ITER_REQUIRE_VALID(block_obj)                              \
00072   do {                                                                  \
00073     if (block_obj->block == NULL)                                       \
00074       {                                                                 \
00075         PyErr_SetString (PyExc_RuntimeError,                            \
00076                          _("Source block for iterator is invalid."));   \
00077         return NULL;                                                    \
00078       }                                                                 \
00079   } while (0)
00080 
00081 static PyTypeObject block_syms_iterator_object_type
00082     CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("block_syms_iterator_object");
00083 static const struct objfile_data *blpy_objfile_data_key;
00084 
00085 static PyObject *
00086 blpy_iter (PyObject *self)
00087 {
00088   block_syms_iterator_object *block_iter_obj;
00089   const struct block *block = NULL;
00090 
00091   BLPY_REQUIRE_VALID (self, block);
00092 
00093   block_iter_obj = PyObject_New (block_syms_iterator_object,
00094                                  &block_syms_iterator_object_type);
00095   if (block_iter_obj == NULL)
00096       return NULL;
00097 
00098   block_iter_obj->block = block;
00099   block_iter_obj->initialized_p = 0;
00100   Py_INCREF (self);
00101   block_iter_obj->source = (block_object *) self;
00102 
00103   return (PyObject *) block_iter_obj;
00104 }
00105 
00106 static PyObject *
00107 blpy_get_start (PyObject *self, void *closure)
00108 {
00109   const struct block *block = NULL;
00110 
00111   BLPY_REQUIRE_VALID (self, block);
00112 
00113   return gdb_py_object_from_ulongest (BLOCK_START (block));
00114 }
00115 
00116 static PyObject *
00117 blpy_get_end (PyObject *self, void *closure)
00118 {
00119   const struct block *block = NULL;
00120 
00121   BLPY_REQUIRE_VALID (self, block);
00122 
00123   return gdb_py_object_from_ulongest (BLOCK_END (block));
00124 }
00125 
00126 static PyObject *
00127 blpy_get_function (PyObject *self, void *closure)
00128 {
00129   struct symbol *sym;
00130   const struct block *block;
00131 
00132   BLPY_REQUIRE_VALID (self, block);
00133 
00134   sym = BLOCK_FUNCTION (block);
00135   if (sym)
00136     return symbol_to_symbol_object (sym);
00137 
00138   Py_RETURN_NONE;
00139 }
00140 
00141 static PyObject *
00142 blpy_get_superblock (PyObject *self, void *closure)
00143 {
00144   const struct block *block;
00145   const struct block *super_block;
00146   block_object *self_obj  = (block_object *) self;
00147 
00148   BLPY_REQUIRE_VALID (self, block);
00149 
00150   super_block = BLOCK_SUPERBLOCK (block);
00151   if (super_block)
00152     return block_to_block_object (super_block, self_obj->objfile);
00153 
00154   Py_RETURN_NONE;
00155 }
00156 
00157 /* Return the global block associated to this block.  */
00158 
00159 static PyObject *
00160 blpy_get_global_block (PyObject *self, void *closure)
00161 {
00162   const struct block *block;
00163   const struct block *global_block;
00164   block_object *self_obj  = (block_object *) self;
00165 
00166   BLPY_REQUIRE_VALID (self, block);
00167 
00168   global_block = block_global_block (block);
00169 
00170   return block_to_block_object (global_block,
00171                                 self_obj->objfile);
00172 
00173 }
00174 
00175 /* Return the static block associated to this block.  Return None
00176    if we cannot get the static block (this is the global block).  */
00177 
00178 static PyObject *
00179 blpy_get_static_block (PyObject *self, void *closure)
00180 {
00181   const struct block *block;
00182   const struct block *static_block;
00183   block_object *self_obj  = (block_object *) self;
00184 
00185   BLPY_REQUIRE_VALID (self, block);
00186 
00187   if (BLOCK_SUPERBLOCK (block) == NULL)
00188     Py_RETURN_NONE;
00189 
00190   static_block = block_static_block (block);
00191 
00192   return block_to_block_object (static_block, self_obj->objfile);
00193 }
00194 
00195 /* Implementation of gdb.Block.is_global (self) -> Boolean.
00196    Returns True if this block object is a global block.  */
00197 
00198 static PyObject *
00199 blpy_is_global (PyObject *self, void *closure)
00200 {
00201   const struct block *block;
00202 
00203   BLPY_REQUIRE_VALID (self, block);
00204 
00205   if (BLOCK_SUPERBLOCK (block))
00206     Py_RETURN_FALSE;
00207 
00208   Py_RETURN_TRUE;
00209 }
00210 
00211 /* Implementation of gdb.Block.is_static (self) -> Boolean.
00212    Returns True if this block object is a static block.  */
00213 
00214 static PyObject *
00215 blpy_is_static (PyObject *self, void *closure)
00216 {
00217   const struct block *block;
00218 
00219   BLPY_REQUIRE_VALID (self, block);
00220 
00221   if (BLOCK_SUPERBLOCK (block) != NULL
00222      && BLOCK_SUPERBLOCK (BLOCK_SUPERBLOCK (block)) == NULL)
00223     Py_RETURN_TRUE;
00224 
00225   Py_RETURN_FALSE;
00226 }
00227 
00228 static void
00229 blpy_dealloc (PyObject *obj)
00230 {
00231   block_object *block = (block_object *) obj;
00232 
00233   if (block->prev)
00234     block->prev->next = block->next;
00235   else if (block->objfile)
00236     {
00237       set_objfile_data (block->objfile, blpy_objfile_data_key,
00238                         block->next);
00239     }
00240   if (block->next)
00241     block->next->prev = block->prev;
00242   block->block = NULL;
00243 }
00244 
00245 /* Given a block, and a block_object that has previously been
00246    allocated and initialized, populate the block_object with the
00247    struct block data.  Also, register the block_object life-cycle
00248    with the life-cycle of the object file associated with this
00249    block, if needed.  */
00250 static void
00251 set_block (block_object *obj, const struct block *block,
00252            struct objfile *objfile)
00253 {
00254   obj->block = block;
00255   obj->prev = NULL;
00256   if (objfile)
00257     {
00258       obj->objfile = objfile;
00259       obj->next = objfile_data (objfile, blpy_objfile_data_key);
00260       if (obj->next)
00261         obj->next->prev = obj;
00262       set_objfile_data (objfile, blpy_objfile_data_key, obj);
00263     }
00264   else
00265     obj->next = NULL;
00266 }
00267 
00268 /* Create a new block object (gdb.Block) that encapsulates the struct
00269    block object from GDB.  */
00270 PyObject *
00271 block_to_block_object (const struct block *block, struct objfile *objfile)
00272 {
00273   block_object *block_obj;
00274 
00275   block_obj = PyObject_New (block_object, &block_object_type);
00276   if (block_obj)
00277     set_block (block_obj, block, objfile);
00278 
00279   return (PyObject *) block_obj;
00280 }
00281 
00282 /* Return struct block reference that is wrapped by this object.  */
00283 const struct block *
00284 block_object_to_block (PyObject *obj)
00285 {
00286   if (! PyObject_TypeCheck (obj, &block_object_type))
00287     return NULL;
00288   return ((block_object *) obj)->block;
00289 }
00290 
00291 /* Return a reference to the block iterator.  */
00292 static PyObject *
00293 blpy_block_syms_iter (PyObject *self)
00294 {
00295   block_syms_iterator_object *iter_obj = (block_syms_iterator_object *) self;
00296 
00297   BLPY_ITER_REQUIRE_VALID (iter_obj->source);
00298 
00299   Py_INCREF (self);
00300   return self;
00301 }
00302 
00303 /* Return the next symbol in the iteration through the block's
00304    dictionary.  */
00305 static PyObject *
00306 blpy_block_syms_iternext (PyObject *self)
00307 {
00308   block_syms_iterator_object *iter_obj = (block_syms_iterator_object *) self;
00309   struct symbol *sym;
00310 
00311   BLPY_ITER_REQUIRE_VALID (iter_obj->source);
00312 
00313   if (!iter_obj->initialized_p)
00314     {
00315       sym = block_iterator_first (iter_obj->block,  &(iter_obj->iter));
00316       iter_obj->initialized_p = 1;
00317     }
00318   else
00319     sym = block_iterator_next (&(iter_obj->iter));
00320 
00321   if (sym == NULL)
00322     {
00323       PyErr_SetString (PyExc_StopIteration, _("Symbol is null."));
00324       return NULL;
00325     }
00326 
00327   return symbol_to_symbol_object (sym);
00328 }
00329 
00330 static void
00331 blpy_block_syms_dealloc (PyObject *obj)
00332 {
00333   block_syms_iterator_object *iter_obj = (block_syms_iterator_object *) obj;
00334 
00335   Py_XDECREF (iter_obj->source);
00336 }
00337 
00338 /* Implementation of gdb.Block.is_valid (self) -> Boolean.
00339    Returns True if this block object still exists in GDB.  */
00340 
00341 static PyObject *
00342 blpy_is_valid (PyObject *self, PyObject *args)
00343 {
00344   const struct block *block;
00345 
00346   block = block_object_to_block (self);
00347   if (block == NULL)
00348     Py_RETURN_FALSE;
00349 
00350   Py_RETURN_TRUE;
00351 }
00352 
00353 /* Implementation of gdb.BlockIterator.is_valid (self) -> Boolean.
00354    Returns True if this block iterator object still exists in GDB  */
00355 
00356 static PyObject *
00357 blpy_iter_is_valid (PyObject *self, PyObject *args)
00358 {
00359   block_syms_iterator_object *iter_obj =
00360     (block_syms_iterator_object *) self;
00361 
00362   if (iter_obj->source->block == NULL)
00363     Py_RETURN_FALSE;
00364 
00365   Py_RETURN_TRUE;
00366 }
00367 
00368 /* Return the innermost lexical block containing the specified pc value,
00369    or 0 if there is none.  */
00370 PyObject *
00371 gdbpy_block_for_pc (PyObject *self, PyObject *args)
00372 {
00373   gdb_py_ulongest pc;
00374   struct block *block = NULL;
00375   struct obj_section *section = NULL;
00376   struct symtab *symtab = NULL;
00377   volatile struct gdb_exception except;
00378 
00379   if (!PyArg_ParseTuple (args, GDB_PY_LLU_ARG, &pc))
00380     return NULL;
00381 
00382   TRY_CATCH (except, RETURN_MASK_ALL)
00383     {
00384       section = find_pc_mapped_section (pc);
00385       symtab = find_pc_sect_symtab (pc, section);
00386 
00387       if (symtab != NULL && symtab->objfile != NULL)
00388         block = block_for_pc (pc);
00389     }
00390   GDB_PY_HANDLE_EXCEPTION (except);
00391 
00392   if (!symtab || symtab->objfile == NULL)
00393     {
00394       PyErr_SetString (PyExc_RuntimeError,
00395                        _("Cannot locate object file for block."));
00396       return NULL;
00397     }
00398 
00399   if (block)
00400     return block_to_block_object (block, symtab->objfile);
00401 
00402   Py_RETURN_NONE;
00403 }
00404 
00405 /* This function is called when an objfile is about to be freed.
00406    Invalidate the block as further actions on the block would result
00407    in bad data.  All access to obj->symbol should be gated by
00408    BLPY_REQUIRE_VALID which will raise an exception on invalid
00409    blocks.  */
00410 static void
00411 del_objfile_blocks (struct objfile *objfile, void *datum)
00412 {
00413   block_object *obj = datum;
00414 
00415   while (obj)
00416     {
00417       block_object *next = obj->next;
00418 
00419       obj->block = NULL;
00420       obj->objfile = NULL;
00421       obj->next = NULL;
00422       obj->prev = NULL;
00423 
00424       obj = next;
00425     }
00426 }
00427 
00428 int
00429 gdbpy_initialize_blocks (void)
00430 {
00431   block_object_type.tp_new = PyType_GenericNew;
00432   if (PyType_Ready (&block_object_type) < 0)
00433     return -1;
00434 
00435   block_syms_iterator_object_type.tp_new = PyType_GenericNew;
00436   if (PyType_Ready (&block_syms_iterator_object_type) < 0)
00437     return -1;
00438 
00439   /* Register an objfile "free" callback so we can properly
00440      invalidate blocks when an object file is about to be
00441      deleted.  */
00442   blpy_objfile_data_key
00443     = register_objfile_data_with_cleanup (NULL, del_objfile_blocks);
00444 
00445   if (gdb_pymodule_addobject (gdb_module, "Block",
00446                               (PyObject *) &block_object_type) < 0)
00447     return -1;
00448 
00449   return gdb_pymodule_addobject (gdb_module, "BlockIterator",
00450                                  (PyObject *) &block_syms_iterator_object_type);
00451 }
00452 
00453 
00454 
00455 static PyMethodDef block_object_methods[] = {
00456   { "is_valid", blpy_is_valid, METH_NOARGS,
00457     "is_valid () -> Boolean.\n\
00458 Return true if this block is valid, false if not." },
00459   {NULL}  /* Sentinel */
00460 };
00461 
00462 static PyGetSetDef block_object_getset[] = {
00463   { "start", blpy_get_start, NULL, "Start address of the block.", NULL },
00464   { "end", blpy_get_end, NULL, "End address of the block.", NULL },
00465   { "function", blpy_get_function, NULL,
00466     "Symbol that names the block, or None.", NULL },
00467   { "superblock", blpy_get_superblock, NULL,
00468     "Block containing the block, or None.", NULL },
00469   { "global_block", blpy_get_global_block, NULL,
00470     "Block containing the global block.", NULL },
00471   { "static_block", blpy_get_static_block, NULL,
00472     "Block containing the static block.", NULL },
00473   { "is_static", blpy_is_static, NULL,
00474     "Whether this block is a static block.", NULL },
00475   { "is_global", blpy_is_global, NULL,
00476     "Whether this block is a global block.", NULL },
00477   { NULL }  /* Sentinel */
00478 };
00479 
00480 PyTypeObject block_object_type = {
00481   PyVarObject_HEAD_INIT (NULL, 0)
00482   "gdb.Block",                    /*tp_name*/
00483   sizeof (block_object),          /*tp_basicsize*/
00484   0,                              /*tp_itemsize*/
00485   blpy_dealloc,                   /*tp_dealloc*/
00486   0,                              /*tp_print*/
00487   0,                              /*tp_getattr*/
00488   0,                              /*tp_setattr*/
00489   0,                              /*tp_compare*/
00490   0,                              /*tp_repr*/
00491   0,                              /*tp_as_number*/
00492   0,                              /*tp_as_sequence*/
00493   0,                              /*tp_as_mapping*/
00494   0,                              /*tp_hash */
00495   0,                              /*tp_call*/
00496   0,                              /*tp_str*/
00497   0,                              /*tp_getattro*/
00498   0,                              /*tp_setattro*/
00499   0,                              /*tp_as_buffer*/
00500   Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_ITER,  /*tp_flags*/
00501   "GDB block object",             /* tp_doc */
00502   0,                              /* tp_traverse */
00503   0,                              /* tp_clear */
00504   0,                              /* tp_richcompare */
00505   0,                              /* tp_weaklistoffset */
00506   blpy_iter,                      /* tp_iter */
00507   0,                              /* tp_iternext */
00508   block_object_methods,           /* tp_methods */
00509   0,                              /* tp_members */
00510   block_object_getset             /* tp_getset */
00511 };
00512 
00513 static PyMethodDef block_iterator_object_methods[] = {
00514   { "is_valid", blpy_iter_is_valid, METH_NOARGS,
00515     "is_valid () -> Boolean.\n\
00516 Return true if this block iterator is valid, false if not." },
00517   {NULL}  /* Sentinel */
00518 };
00519 
00520 static PyTypeObject block_syms_iterator_object_type = {
00521   PyVarObject_HEAD_INIT (NULL, 0)
00522   "gdb.BlockIterator",            /*tp_name*/
00523   sizeof (block_syms_iterator_object),        /*tp_basicsize*/
00524   0,                              /*tp_itemsize*/
00525   blpy_block_syms_dealloc,        /*tp_dealloc*/
00526   0,                              /*tp_print*/
00527   0,                              /*tp_getattr*/
00528   0,                              /*tp_setattr*/
00529   0,                              /*tp_compare*/
00530   0,                              /*tp_repr*/
00531   0,                              /*tp_as_number*/
00532   0,                              /*tp_as_sequence*/
00533   0,                              /*tp_as_mapping*/
00534   0,                              /*tp_hash */
00535   0,                              /*tp_call*/
00536   0,                              /*tp_str*/
00537   0,                              /*tp_getattro*/
00538   0,                              /*tp_setattro*/
00539   0,                              /*tp_as_buffer*/
00540   Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_ITER,  /*tp_flags*/
00541   "GDB block syms iterator object",           /*tp_doc */
00542   0,                              /*tp_traverse */
00543   0,                              /*tp_clear */
00544   0,                              /*tp_richcompare */
00545   0,                              /*tp_weaklistoffset */
00546   blpy_block_syms_iter,           /*tp_iter */
00547   blpy_block_syms_iternext,       /*tp_iternext */
00548   block_iterator_object_methods   /*tp_methods */
00549 };
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines