GDB (API)
|
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 };