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 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 }; 513