1 /* Python interface to blocks. 2 3 Copyright (C) 2008-2023 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 struct 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 block_object *prev; 38 block_object *next; 39 }; 40 41 struct block_syms_iterator_object { 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 block_object *source; 53 }; 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 /* This is called when an objfile is about to be freed. 81 Invalidate the block as further actions on the block would result 82 in bad data. All access to obj->symbol should be gated by 83 BLPY_REQUIRE_VALID which will raise an exception on invalid 84 blocks. */ 85 struct blpy_deleter 86 { 87 void operator() (block_object *obj) 88 { 89 while (obj) 90 { 91 block_object *next = obj->next; 92 93 obj->block = NULL; 94 obj->objfile = NULL; 95 obj->next = NULL; 96 obj->prev = NULL; 97 98 obj = next; 99 } 100 } 101 }; 102 103 extern PyTypeObject block_syms_iterator_object_type 104 CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("block_syms_iterator_object"); 105 static const registry<objfile>::key<block_object, blpy_deleter> 106 blpy_objfile_data_key; 107 108 static PyObject * 109 blpy_iter (PyObject *self) 110 { 111 block_syms_iterator_object *block_iter_obj; 112 const struct block *block = NULL; 113 114 BLPY_REQUIRE_VALID (self, block); 115 116 block_iter_obj = PyObject_New (block_syms_iterator_object, 117 &block_syms_iterator_object_type); 118 if (block_iter_obj == NULL) 119 return NULL; 120 121 block_iter_obj->block = block; 122 block_iter_obj->initialized_p = 0; 123 Py_INCREF (self); 124 block_iter_obj->source = (block_object *) self; 125 126 return (PyObject *) block_iter_obj; 127 } 128 129 static PyObject * 130 blpy_get_start (PyObject *self, void *closure) 131 { 132 const struct block *block = NULL; 133 134 BLPY_REQUIRE_VALID (self, block); 135 136 return gdb_py_object_from_ulongest (block->start ()).release (); 137 } 138 139 static PyObject * 140 blpy_get_end (PyObject *self, void *closure) 141 { 142 const struct block *block = NULL; 143 144 BLPY_REQUIRE_VALID (self, block); 145 146 return gdb_py_object_from_ulongest (block->end ()).release (); 147 } 148 149 static PyObject * 150 blpy_get_function (PyObject *self, void *closure) 151 { 152 struct symbol *sym; 153 const struct block *block; 154 155 BLPY_REQUIRE_VALID (self, block); 156 157 sym = block->function (); 158 if (sym) 159 return symbol_to_symbol_object (sym); 160 161 Py_RETURN_NONE; 162 } 163 164 static PyObject * 165 blpy_get_superblock (PyObject *self, void *closure) 166 { 167 const struct block *block; 168 const struct block *super_block; 169 block_object *self_obj = (block_object *) self; 170 171 BLPY_REQUIRE_VALID (self, block); 172 173 super_block = block->superblock (); 174 if (super_block) 175 return block_to_block_object (super_block, self_obj->objfile); 176 177 Py_RETURN_NONE; 178 } 179 180 /* Return the global block associated to this block. */ 181 182 static PyObject * 183 blpy_get_global_block (PyObject *self, void *closure) 184 { 185 const struct block *block; 186 const struct block *global_block; 187 block_object *self_obj = (block_object *) self; 188 189 BLPY_REQUIRE_VALID (self, block); 190 191 global_block = block_global_block (block); 192 193 return block_to_block_object (global_block, 194 self_obj->objfile); 195 196 } 197 198 /* Return the static block associated to this block. Return None 199 if we cannot get the static block (this is the global block). */ 200 201 static PyObject * 202 blpy_get_static_block (PyObject *self, void *closure) 203 { 204 const struct block *block; 205 const struct block *static_block; 206 block_object *self_obj = (block_object *) self; 207 208 BLPY_REQUIRE_VALID (self, block); 209 210 if (block->superblock () == NULL) 211 Py_RETURN_NONE; 212 213 static_block = block_static_block (block); 214 215 return block_to_block_object (static_block, self_obj->objfile); 216 } 217 218 /* Implementation of gdb.Block.is_global (self) -> Boolean. 219 Returns True if this block object is a global block. */ 220 221 static PyObject * 222 blpy_is_global (PyObject *self, void *closure) 223 { 224 const struct block *block; 225 226 BLPY_REQUIRE_VALID (self, block); 227 228 if (block->superblock ()) 229 Py_RETURN_FALSE; 230 231 Py_RETURN_TRUE; 232 } 233 234 /* Implementation of gdb.Block.is_static (self) -> Boolean. 235 Returns True if this block object is a static block. */ 236 237 static PyObject * 238 blpy_is_static (PyObject *self, void *closure) 239 { 240 const struct block *block; 241 242 BLPY_REQUIRE_VALID (self, block); 243 244 if (block->superblock () != NULL 245 && block->superblock ()->superblock () == NULL) 246 Py_RETURN_TRUE; 247 248 Py_RETURN_FALSE; 249 } 250 251 /* Given a string, returns the gdb.Symbol representing that symbol in this 252 block. If such a symbol does not exist, returns NULL with a Python 253 exception. */ 254 255 static PyObject * 256 blpy_getitem (PyObject *self, PyObject *key) 257 { 258 const struct block *block; 259 260 BLPY_REQUIRE_VALID (self, block); 261 262 gdb::unique_xmalloc_ptr<char> name = python_string_to_host_string (key); 263 if (name == nullptr) 264 return nullptr; 265 266 lookup_name_info lookup_name (name.get(), symbol_name_match_type::FULL); 267 268 /* We use ALL_BLOCK_SYMBOLS_WITH_NAME instead of block_lookup_symbol so 269 that we can look up symbols irrespective of the domain, matching the 270 iterator. It would be confusing if the iterator returns symbols you 271 can't find via getitem. */ 272 struct block_iterator iter; 273 struct symbol *sym = nullptr; 274 ALL_BLOCK_SYMBOLS_WITH_NAME (block, lookup_name, iter, sym) 275 { 276 /* Just stop at the first match */ 277 break; 278 } 279 280 if (sym == nullptr) 281 { 282 PyErr_SetObject (PyExc_KeyError, key); 283 return nullptr; 284 } 285 return symbol_to_symbol_object (sym); 286 } 287 288 static void 289 blpy_dealloc (PyObject *obj) 290 { 291 block_object *block = (block_object *) obj; 292 293 if (block->prev) 294 block->prev->next = block->next; 295 else if (block->objfile) 296 blpy_objfile_data_key.set (block->objfile, block->next); 297 if (block->next) 298 block->next->prev = block->prev; 299 block->block = NULL; 300 Py_TYPE (obj)->tp_free (obj); 301 } 302 303 /* Given a block, and a block_object that has previously been 304 allocated and initialized, populate the block_object with the 305 struct block data. Also, register the block_object life-cycle 306 with the life-cycle of the object file associated with this 307 block, if needed. */ 308 static void 309 set_block (block_object *obj, const struct block *block, 310 struct objfile *objfile) 311 { 312 obj->block = block; 313 obj->prev = NULL; 314 if (objfile) 315 { 316 obj->objfile = objfile; 317 obj->next = blpy_objfile_data_key.get (objfile); 318 if (obj->next) 319 obj->next->prev = obj; 320 blpy_objfile_data_key.set (objfile, obj); 321 } 322 else 323 obj->next = NULL; 324 } 325 326 /* Create a new block object (gdb.Block) that encapsulates the struct 327 block object from GDB. */ 328 PyObject * 329 block_to_block_object (const struct block *block, struct objfile *objfile) 330 { 331 block_object *block_obj; 332 333 block_obj = PyObject_New (block_object, &block_object_type); 334 if (block_obj) 335 set_block (block_obj, block, objfile); 336 337 return (PyObject *) block_obj; 338 } 339 340 /* Return struct block reference that is wrapped by this object. */ 341 const struct block * 342 block_object_to_block (PyObject *obj) 343 { 344 if (! PyObject_TypeCheck (obj, &block_object_type)) 345 return NULL; 346 return ((block_object *) obj)->block; 347 } 348 349 /* Return a reference to the block iterator. */ 350 static PyObject * 351 blpy_block_syms_iter (PyObject *self) 352 { 353 block_syms_iterator_object *iter_obj = (block_syms_iterator_object *) self; 354 355 BLPY_ITER_REQUIRE_VALID (iter_obj->source); 356 357 Py_INCREF (self); 358 return self; 359 } 360 361 /* Return the next symbol in the iteration through the block's 362 dictionary. */ 363 static PyObject * 364 blpy_block_syms_iternext (PyObject *self) 365 { 366 block_syms_iterator_object *iter_obj = (block_syms_iterator_object *) self; 367 struct symbol *sym; 368 369 BLPY_ITER_REQUIRE_VALID (iter_obj->source); 370 371 if (!iter_obj->initialized_p) 372 { 373 sym = block_iterator_first (iter_obj->block, &(iter_obj->iter)); 374 iter_obj->initialized_p = 1; 375 } 376 else 377 sym = block_iterator_next (&(iter_obj->iter)); 378 379 if (sym == NULL) 380 { 381 PyErr_SetString (PyExc_StopIteration, _("Symbol is null.")); 382 return NULL; 383 } 384 385 return symbol_to_symbol_object (sym); 386 } 387 388 static void 389 blpy_block_syms_dealloc (PyObject *obj) 390 { 391 block_syms_iterator_object *iter_obj = (block_syms_iterator_object *) obj; 392 393 Py_XDECREF (iter_obj->source); 394 Py_TYPE (obj)->tp_free (obj); 395 } 396 397 /* Implementation of gdb.Block.is_valid (self) -> Boolean. 398 Returns True if this block object still exists in GDB. */ 399 400 static PyObject * 401 blpy_is_valid (PyObject *self, PyObject *args) 402 { 403 const struct block *block; 404 405 block = block_object_to_block (self); 406 if (block == NULL) 407 Py_RETURN_FALSE; 408 409 Py_RETURN_TRUE; 410 } 411 412 /* Implementation of gdb.BlockIterator.is_valid (self) -> Boolean. 413 Returns True if this block iterator object still exists in GDB */ 414 415 static PyObject * 416 blpy_iter_is_valid (PyObject *self, PyObject *args) 417 { 418 block_syms_iterator_object *iter_obj = 419 (block_syms_iterator_object *) self; 420 421 if (iter_obj->source->block == NULL) 422 Py_RETURN_FALSE; 423 424 Py_RETURN_TRUE; 425 } 426 427 int 428 gdbpy_initialize_blocks (void) 429 { 430 block_object_type.tp_new = PyType_GenericNew; 431 if (PyType_Ready (&block_object_type) < 0) 432 return -1; 433 434 block_syms_iterator_object_type.tp_new = PyType_GenericNew; 435 if (PyType_Ready (&block_syms_iterator_object_type) < 0) 436 return -1; 437 438 if (gdb_pymodule_addobject (gdb_module, "Block", 439 (PyObject *) &block_object_type) < 0) 440 return -1; 441 442 return gdb_pymodule_addobject (gdb_module, "BlockIterator", 443 (PyObject *) &block_syms_iterator_object_type); 444 } 445 446 447 448 static PyMethodDef block_object_methods[] = { 449 { "is_valid", blpy_is_valid, METH_NOARGS, 450 "is_valid () -> Boolean.\n\ 451 Return true if this block is valid, false if not." }, 452 {NULL} /* Sentinel */ 453 }; 454 455 static gdb_PyGetSetDef block_object_getset[] = { 456 { "start", blpy_get_start, NULL, "Start address of the block.", NULL }, 457 { "end", blpy_get_end, NULL, "End address of the block.", NULL }, 458 { "function", blpy_get_function, NULL, 459 "Symbol that names the block, or None.", NULL }, 460 { "superblock", blpy_get_superblock, NULL, 461 "Block containing the block, or None.", NULL }, 462 { "global_block", blpy_get_global_block, NULL, 463 "Block containing the global block.", NULL }, 464 { "static_block", blpy_get_static_block, NULL, 465 "Block containing the static block.", NULL }, 466 { "is_static", blpy_is_static, NULL, 467 "Whether this block is a static block.", NULL }, 468 { "is_global", blpy_is_global, NULL, 469 "Whether this block is a global block.", NULL }, 470 { NULL } /* Sentinel */ 471 }; 472 473 static PyMappingMethods block_object_as_mapping = { 474 NULL, 475 blpy_getitem, 476 NULL 477 }; 478 479 PyTypeObject block_object_type = { 480 PyVarObject_HEAD_INIT (NULL, 0) 481 "gdb.Block", /*tp_name*/ 482 sizeof (block_object), /*tp_basicsize*/ 483 0, /*tp_itemsize*/ 484 blpy_dealloc, /*tp_dealloc*/ 485 0, /*tp_print*/ 486 0, /*tp_getattr*/ 487 0, /*tp_setattr*/ 488 0, /*tp_compare*/ 489 0, /*tp_repr*/ 490 0, /*tp_as_number*/ 491 0, /*tp_as_sequence*/ 492 &block_object_as_mapping, /*tp_as_mapping*/ 493 0, /*tp_hash */ 494 0, /*tp_call*/ 495 0, /*tp_str*/ 496 0, /*tp_getattro*/ 497 0, /*tp_setattro*/ 498 0, /*tp_as_buffer*/ 499 Py_TPFLAGS_DEFAULT, /*tp_flags*/ 500 "GDB block object", /* tp_doc */ 501 0, /* tp_traverse */ 502 0, /* tp_clear */ 503 0, /* tp_richcompare */ 504 0, /* tp_weaklistoffset */ 505 blpy_iter, /* tp_iter */ 506 0, /* tp_iternext */ 507 block_object_methods, /* tp_methods */ 508 0, /* tp_members */ 509 block_object_getset /* tp_getset */ 510 }; 511 512 static PyMethodDef block_iterator_object_methods[] = { 513 { "is_valid", blpy_iter_is_valid, METH_NOARGS, 514 "is_valid () -> Boolean.\n\ 515 Return true if this block iterator is valid, false if not." }, 516 {NULL} /* Sentinel */ 517 }; 518 519 PyTypeObject block_syms_iterator_object_type = { 520 PyVarObject_HEAD_INIT (NULL, 0) 521 "gdb.BlockIterator", /*tp_name*/ 522 sizeof (block_syms_iterator_object), /*tp_basicsize*/ 523 0, /*tp_itemsize*/ 524 blpy_block_syms_dealloc, /*tp_dealloc*/ 525 0, /*tp_print*/ 526 0, /*tp_getattr*/ 527 0, /*tp_setattr*/ 528 0, /*tp_compare*/ 529 0, /*tp_repr*/ 530 0, /*tp_as_number*/ 531 0, /*tp_as_sequence*/ 532 0, /*tp_as_mapping*/ 533 0, /*tp_hash */ 534 0, /*tp_call*/ 535 0, /*tp_str*/ 536 0, /*tp_getattro*/ 537 0, /*tp_setattro*/ 538 0, /*tp_as_buffer*/ 539 Py_TPFLAGS_DEFAULT, /*tp_flags*/ 540 "GDB block syms iterator object", /*tp_doc */ 541 0, /*tp_traverse */ 542 0, /*tp_clear */ 543 0, /*tp_richcompare */ 544 0, /*tp_weaklistoffset */ 545 blpy_block_syms_iter, /*tp_iter */ 546 blpy_block_syms_iternext, /*tp_iternext */ 547 block_iterator_object_methods /*tp_methods */ 548 }; 549