1 /* Python interface to symbol tables. 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 "charset.h" 22 #include "symtab.h" 23 #include "source.h" 24 #include "python-internal.h" 25 #include "objfiles.h" 26 #include "block.h" 27 28 struct symtab_object { 29 PyObject_HEAD 30 /* The GDB Symbol table structure. */ 31 struct symtab *symtab; 32 /* A symtab object is associated with an objfile, so keep track with 33 a doubly-linked list, rooted in the objfile. This allows 34 invalidation of the underlying struct symtab when the objfile is 35 deleted. */ 36 symtab_object *prev; 37 symtab_object *next; 38 }; 39 40 /* This function is called when an objfile is about to be freed. 41 Invalidate the symbol table as further actions on the symbol table 42 would result in bad data. All access to obj->symtab should be 43 gated by STPY_REQUIRE_VALID which will raise an exception on 44 invalid symbol tables. */ 45 struct stpy_deleter 46 { 47 void operator() (symtab_object *obj) 48 { 49 while (obj) 50 { 51 symtab_object *next = obj->next; 52 53 obj->symtab = NULL; 54 obj->next = NULL; 55 obj->prev = NULL; 56 obj = next; 57 } 58 } 59 }; 60 61 extern PyTypeObject symtab_object_type 62 CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("symtab_object"); 63 static const registry<objfile>::key<symtab_object, stpy_deleter> 64 stpy_objfile_data_key; 65 66 /* Require a valid symbol table. All access to symtab_object->symtab 67 should be gated by this call. */ 68 #define STPY_REQUIRE_VALID(symtab_obj, symtab) \ 69 do { \ 70 symtab = symtab_object_to_symtab (symtab_obj); \ 71 if (symtab == NULL) \ 72 { \ 73 PyErr_SetString (PyExc_RuntimeError, \ 74 _("Symbol Table is invalid.")); \ 75 return NULL; \ 76 } \ 77 } while (0) 78 79 struct sal_object { 80 PyObject_HEAD 81 /* The GDB Symbol table structure. */ 82 PyObject *symtab; 83 /* The GDB Symbol table and line structure. */ 84 struct symtab_and_line *sal; 85 /* A Symtab and line object is associated with an objfile, so keep 86 track with a doubly-linked list, rooted in the objfile. This 87 allows invalidation of the underlying struct symtab_and_line 88 when the objfile is deleted. */ 89 sal_object *prev; 90 sal_object *next; 91 }; 92 93 /* This is called when an objfile is about to be freed. Invalidate 94 the sal object as further actions on the sal would result in bad 95 data. All access to obj->sal should be gated by 96 SALPY_REQUIRE_VALID which will raise an exception on invalid symbol 97 table and line objects. */ 98 struct salpy_deleter 99 { 100 void operator() (sal_object *obj) 101 { 102 gdbpy_enter enter_py; 103 104 while (obj) 105 { 106 sal_object *next = obj->next; 107 108 gdbpy_ref<> tmp (obj->symtab); 109 obj->symtab = Py_None; 110 Py_INCREF (Py_None); 111 112 obj->next = NULL; 113 obj->prev = NULL; 114 xfree (obj->sal); 115 obj->sal = NULL; 116 117 obj = next; 118 } 119 } 120 }; 121 122 extern PyTypeObject sal_object_type 123 CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("sal_object"); 124 static const registry<objfile>::key<sal_object, salpy_deleter> 125 salpy_objfile_data_key; 126 127 /* Require a valid symbol table and line object. All access to 128 sal_object->sal should be gated by this call. */ 129 #define SALPY_REQUIRE_VALID(sal_obj, sal) \ 130 do { \ 131 sal = sal_object_to_symtab_and_line (sal_obj); \ 132 if (sal == NULL) \ 133 { \ 134 PyErr_SetString (PyExc_RuntimeError, \ 135 _("Symbol Table and Line is invalid.")); \ 136 return NULL; \ 137 } \ 138 } while (0) 139 140 static PyObject * 141 stpy_str (PyObject *self) 142 { 143 PyObject *result; 144 struct symtab *symtab = NULL; 145 146 STPY_REQUIRE_VALID (self, symtab); 147 148 result = PyUnicode_FromString (symtab_to_filename_for_display (symtab)); 149 150 return result; 151 } 152 153 static PyObject * 154 stpy_get_filename (PyObject *self, void *closure) 155 { 156 PyObject *str_obj; 157 struct symtab *symtab = NULL; 158 const char *filename; 159 160 STPY_REQUIRE_VALID (self, symtab); 161 filename = symtab_to_filename_for_display (symtab); 162 163 str_obj = host_string_to_python_string (filename).release (); 164 return str_obj; 165 } 166 167 static PyObject * 168 stpy_get_objfile (PyObject *self, void *closure) 169 { 170 struct symtab *symtab = NULL; 171 172 STPY_REQUIRE_VALID (self, symtab); 173 174 return objfile_to_objfile_object (symtab->compunit ()->objfile ()).release (); 175 } 176 177 /* Getter function for symtab.producer. */ 178 179 static PyObject * 180 stpy_get_producer (PyObject *self, void *closure) 181 { 182 struct symtab *symtab = NULL; 183 struct compunit_symtab *cust; 184 185 STPY_REQUIRE_VALID (self, symtab); 186 cust = symtab->compunit (); 187 if (cust->producer () != nullptr) 188 { 189 const char *producer = cust->producer (); 190 191 return host_string_to_python_string (producer).release (); 192 } 193 194 Py_RETURN_NONE; 195 } 196 197 static PyObject * 198 stpy_fullname (PyObject *self, PyObject *args) 199 { 200 const char *fullname; 201 struct symtab *symtab = NULL; 202 203 STPY_REQUIRE_VALID (self, symtab); 204 205 fullname = symtab_to_fullname (symtab); 206 207 return host_string_to_python_string (fullname).release (); 208 } 209 210 /* Implementation of gdb.Symtab.is_valid (self) -> Boolean. 211 Returns True if this Symbol table still exists in GDB. */ 212 213 static PyObject * 214 stpy_is_valid (PyObject *self, PyObject *args) 215 { 216 struct symtab *symtab = NULL; 217 218 symtab = symtab_object_to_symtab (self); 219 if (symtab == NULL) 220 Py_RETURN_FALSE; 221 222 Py_RETURN_TRUE; 223 } 224 225 /* Return the GLOBAL_BLOCK of the underlying symtab. */ 226 227 static PyObject * 228 stpy_global_block (PyObject *self, PyObject *args) 229 { 230 struct symtab *symtab = NULL; 231 const struct blockvector *blockvector; 232 233 STPY_REQUIRE_VALID (self, symtab); 234 235 blockvector = symtab->compunit ()->blockvector (); 236 const struct block *block = blockvector->global_block (); 237 238 return block_to_block_object (block, symtab->compunit ()->objfile ()); 239 } 240 241 /* Return the STATIC_BLOCK of the underlying symtab. */ 242 243 static PyObject * 244 stpy_static_block (PyObject *self, PyObject *args) 245 { 246 struct symtab *symtab = NULL; 247 const struct blockvector *blockvector; 248 249 STPY_REQUIRE_VALID (self, symtab); 250 251 blockvector = symtab->compunit ()->blockvector (); 252 const struct block *block = blockvector->static_block (); 253 254 return block_to_block_object (block, symtab->compunit ()->objfile ()); 255 } 256 257 /* Implementation of gdb.Symtab.linetable (self) -> gdb.LineTable. 258 Returns a gdb.LineTable object corresponding to this symbol 259 table. */ 260 261 static PyObject * 262 stpy_get_linetable (PyObject *self, PyObject *args) 263 { 264 struct symtab *symtab = NULL; 265 266 STPY_REQUIRE_VALID (self, symtab); 267 268 return symtab_to_linetable_object (self); 269 } 270 271 static PyObject * 272 salpy_str (PyObject *self) 273 { 274 const char *filename; 275 sal_object *sal_obj; 276 struct symtab_and_line *sal = NULL; 277 278 SALPY_REQUIRE_VALID (self, sal); 279 280 sal_obj = (sal_object *) self; 281 if (sal_obj->symtab == Py_None) 282 filename = "<unknown>"; 283 else 284 { 285 symtab *symtab = symtab_object_to_symtab (sal_obj->symtab); 286 filename = symtab_to_filename_for_display (symtab); 287 } 288 289 return PyUnicode_FromFormat ("symbol and line for %s, line %d", filename, 290 sal->line); 291 } 292 293 static void 294 stpy_dealloc (PyObject *obj) 295 { 296 symtab_object *symtab = (symtab_object *) obj; 297 298 if (symtab->prev) 299 symtab->prev->next = symtab->next; 300 else if (symtab->symtab) 301 stpy_objfile_data_key.set (symtab->symtab->compunit ()->objfile (), 302 symtab->next); 303 if (symtab->next) 304 symtab->next->prev = symtab->prev; 305 symtab->symtab = NULL; 306 Py_TYPE (obj)->tp_free (obj); 307 } 308 309 310 static PyObject * 311 salpy_get_pc (PyObject *self, void *closure) 312 { 313 struct symtab_and_line *sal = NULL; 314 315 SALPY_REQUIRE_VALID (self, sal); 316 317 return gdb_py_object_from_ulongest (sal->pc).release (); 318 } 319 320 /* Implementation of the get method for the 'last' attribute of 321 gdb.Symtab_and_line. */ 322 323 static PyObject * 324 salpy_get_last (PyObject *self, void *closure) 325 { 326 struct symtab_and_line *sal = NULL; 327 328 SALPY_REQUIRE_VALID (self, sal); 329 330 if (sal->end > 0) 331 return gdb_py_object_from_ulongest (sal->end - 1).release (); 332 else 333 Py_RETURN_NONE; 334 } 335 336 static PyObject * 337 salpy_get_line (PyObject *self, void *closure) 338 { 339 struct symtab_and_line *sal = NULL; 340 341 SALPY_REQUIRE_VALID (self, sal); 342 343 return gdb_py_object_from_longest (sal->line).release (); 344 } 345 346 static PyObject * 347 salpy_get_symtab (PyObject *self, void *closure) 348 { 349 struct symtab_and_line *sal; 350 sal_object *self_sal = (sal_object *) self; 351 352 SALPY_REQUIRE_VALID (self, sal); 353 354 Py_INCREF (self_sal->symtab); 355 356 return (PyObject *) self_sal->symtab; 357 } 358 359 /* Implementation of gdb.Symtab_and_line.is_valid (self) -> Boolean. 360 Returns True if this Symbol table and line object still exists GDB. */ 361 362 static PyObject * 363 salpy_is_valid (PyObject *self, PyObject *args) 364 { 365 struct symtab_and_line *sal; 366 367 sal = sal_object_to_symtab_and_line (self); 368 if (sal == NULL) 369 Py_RETURN_FALSE; 370 371 Py_RETURN_TRUE; 372 } 373 374 static void 375 salpy_dealloc (PyObject *self) 376 { 377 sal_object *self_sal = (sal_object *) self; 378 379 if (self_sal->prev) 380 self_sal->prev->next = self_sal->next; 381 else if (self_sal->symtab != Py_None) 382 salpy_objfile_data_key.set 383 (symtab_object_to_symtab (self_sal->symtab)->compunit ()->objfile (), 384 self_sal->next); 385 386 if (self_sal->next) 387 self_sal->next->prev = self_sal->prev; 388 389 Py_DECREF (self_sal->symtab); 390 xfree (self_sal->sal); 391 Py_TYPE (self)->tp_free (self); 392 } 393 394 /* Given a sal, and a sal_object that has previously been allocated 395 and initialized, populate the sal_object with the struct sal data. 396 Also, register the sal_object life-cycle with the life-cycle of the 397 object file associated with this sal, if needed. If a failure 398 occurs during the sal population, this function will return -1. */ 399 static int CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION 400 set_sal (sal_object *sal_obj, struct symtab_and_line sal) 401 { 402 PyObject *symtab_obj; 403 404 if (sal.symtab) 405 { 406 symtab_obj = symtab_to_symtab_object (sal.symtab); 407 /* If a symtab existed in the sal, but it cannot be duplicated, 408 we exit. */ 409 if (symtab_obj == NULL) 410 return -1; 411 } 412 else 413 { 414 symtab_obj = Py_None; 415 Py_INCREF (Py_None); 416 } 417 418 sal_obj->sal = ((struct symtab_and_line *) 419 xmemdup (&sal, sizeof (struct symtab_and_line), 420 sizeof (struct symtab_and_line))); 421 sal_obj->symtab = symtab_obj; 422 sal_obj->prev = NULL; 423 424 /* If the SAL does not have a symtab, we do not add it to the 425 objfile cleanup observer linked list. */ 426 if (sal_obj->symtab != Py_None) 427 { 428 symtab *symtab = symtab_object_to_symtab (sal_obj->symtab); 429 430 sal_obj->next 431 = salpy_objfile_data_key.get (symtab->compunit ()->objfile ()); 432 if (sal_obj->next) 433 sal_obj->next->prev = sal_obj; 434 435 salpy_objfile_data_key.set (symtab->compunit ()->objfile (), sal_obj); 436 } 437 else 438 sal_obj->next = NULL; 439 440 return 0; 441 } 442 443 /* Given a symtab, and a symtab_object that has previously been 444 allocated and initialized, populate the symtab_object with the 445 struct symtab data. Also, register the symtab_object life-cycle 446 with the life-cycle of the object file associated with this 447 symtab, if needed. */ 448 static void 449 set_symtab (symtab_object *obj, struct symtab *symtab) 450 { 451 obj->symtab = symtab; 452 obj->prev = NULL; 453 if (symtab) 454 { 455 obj->next = stpy_objfile_data_key.get (symtab->compunit ()->objfile ()); 456 if (obj->next) 457 obj->next->prev = obj; 458 stpy_objfile_data_key.set (symtab->compunit ()->objfile (), obj); 459 } 460 else 461 obj->next = NULL; 462 } 463 464 /* Create a new symbol table (gdb.Symtab) object that encapsulates the 465 symtab structure from GDB. */ 466 PyObject * 467 symtab_to_symtab_object (struct symtab *symtab) 468 { 469 symtab_object *symtab_obj; 470 471 symtab_obj = PyObject_New (symtab_object, &symtab_object_type); 472 if (symtab_obj) 473 set_symtab (symtab_obj, symtab); 474 475 return (PyObject *) symtab_obj; 476 } 477 478 /* Create a new symtab and line (gdb.Symtab_and_line) object 479 that encapsulates the symtab_and_line structure from GDB. */ 480 PyObject * 481 symtab_and_line_to_sal_object (struct symtab_and_line sal) 482 { 483 gdbpy_ref<sal_object> sal_obj (PyObject_New (sal_object, &sal_object_type)); 484 if (sal_obj != NULL) 485 { 486 if (set_sal (sal_obj.get (), sal) < 0) 487 return NULL; 488 } 489 490 return (PyObject *) sal_obj.release (); 491 } 492 493 /* Return struct symtab_and_line reference that is wrapped by this 494 object. */ 495 struct symtab_and_line * 496 sal_object_to_symtab_and_line (PyObject *obj) 497 { 498 if (! PyObject_TypeCheck (obj, &sal_object_type)) 499 return NULL; 500 return ((sal_object *) obj)->sal; 501 } 502 503 /* Return struct symtab reference that is wrapped by this object. */ 504 struct symtab * 505 symtab_object_to_symtab (PyObject *obj) 506 { 507 if (! PyObject_TypeCheck (obj, &symtab_object_type)) 508 return NULL; 509 return ((symtab_object *) obj)->symtab; 510 } 511 512 int 513 gdbpy_initialize_symtabs (void) 514 { 515 symtab_object_type.tp_new = PyType_GenericNew; 516 if (PyType_Ready (&symtab_object_type) < 0) 517 return -1; 518 519 sal_object_type.tp_new = PyType_GenericNew; 520 if (PyType_Ready (&sal_object_type) < 0) 521 return -1; 522 523 if (gdb_pymodule_addobject (gdb_module, "Symtab", 524 (PyObject *) &symtab_object_type) < 0) 525 return -1; 526 527 return gdb_pymodule_addobject (gdb_module, "Symtab_and_line", 528 (PyObject *) &sal_object_type); 529 } 530 531 532 533 static gdb_PyGetSetDef symtab_object_getset[] = { 534 { "filename", stpy_get_filename, NULL, 535 "The symbol table's source filename.", NULL }, 536 { "objfile", stpy_get_objfile, NULL, "The symtab's objfile.", 537 NULL }, 538 { "producer", stpy_get_producer, NULL, 539 "The name/version of the program that compiled this symtab.", NULL }, 540 {NULL} /* Sentinel */ 541 }; 542 543 static PyMethodDef symtab_object_methods[] = { 544 { "is_valid", stpy_is_valid, METH_NOARGS, 545 "is_valid () -> Boolean.\n\ 546 Return true if this symbol table is valid, false if not." }, 547 { "fullname", stpy_fullname, METH_NOARGS, 548 "fullname () -> String.\n\ 549 Return the symtab's full source filename." }, 550 { "global_block", stpy_global_block, METH_NOARGS, 551 "global_block () -> gdb.Block.\n\ 552 Return the global block of the symbol table." }, 553 { "static_block", stpy_static_block, METH_NOARGS, 554 "static_block () -> gdb.Block.\n\ 555 Return the static block of the symbol table." }, 556 { "linetable", stpy_get_linetable, METH_NOARGS, 557 "linetable () -> gdb.LineTable.\n\ 558 Return the LineTable associated with this symbol table" }, 559 {NULL} /* Sentinel */ 560 }; 561 562 PyTypeObject symtab_object_type = { 563 PyVarObject_HEAD_INIT (NULL, 0) 564 "gdb.Symtab", /*tp_name*/ 565 sizeof (symtab_object), /*tp_basicsize*/ 566 0, /*tp_itemsize*/ 567 stpy_dealloc, /*tp_dealloc*/ 568 0, /*tp_print*/ 569 0, /*tp_getattr*/ 570 0, /*tp_setattr*/ 571 0, /*tp_compare*/ 572 0, /*tp_repr*/ 573 0, /*tp_as_number*/ 574 0, /*tp_as_sequence*/ 575 0, /*tp_as_mapping*/ 576 0, /*tp_hash */ 577 0, /*tp_call*/ 578 stpy_str, /*tp_str*/ 579 0, /*tp_getattro*/ 580 0, /*tp_setattro*/ 581 0, /*tp_as_buffer*/ 582 Py_TPFLAGS_DEFAULT, /*tp_flags*/ 583 "GDB symtab object", /*tp_doc */ 584 0, /*tp_traverse */ 585 0, /*tp_clear */ 586 0, /*tp_richcompare */ 587 0, /*tp_weaklistoffset */ 588 0, /*tp_iter */ 589 0, /*tp_iternext */ 590 symtab_object_methods, /*tp_methods */ 591 0, /*tp_members */ 592 symtab_object_getset /*tp_getset */ 593 }; 594 595 static gdb_PyGetSetDef sal_object_getset[] = { 596 { "symtab", salpy_get_symtab, NULL, "Symtab object.", NULL }, 597 { "pc", salpy_get_pc, NULL, "Return the symtab_and_line's pc.", NULL }, 598 { "last", salpy_get_last, NULL, 599 "Return the symtab_and_line's last address.", NULL }, 600 { "line", salpy_get_line, NULL, 601 "Return the symtab_and_line's line.", NULL }, 602 {NULL} /* Sentinel */ 603 }; 604 605 static PyMethodDef sal_object_methods[] = { 606 { "is_valid", salpy_is_valid, METH_NOARGS, 607 "is_valid () -> Boolean.\n\ 608 Return true if this symbol table and line is valid, false if not." }, 609 {NULL} /* Sentinel */ 610 }; 611 612 PyTypeObject sal_object_type = { 613 PyVarObject_HEAD_INIT (NULL, 0) 614 "gdb.Symtab_and_line", /*tp_name*/ 615 sizeof (sal_object), /*tp_basicsize*/ 616 0, /*tp_itemsize*/ 617 salpy_dealloc, /*tp_dealloc*/ 618 0, /*tp_print*/ 619 0, /*tp_getattr*/ 620 0, /*tp_setattr*/ 621 0, /*tp_compare*/ 622 0, /*tp_repr*/ 623 0, /*tp_as_number*/ 624 0, /*tp_as_sequence*/ 625 0, /*tp_as_mapping*/ 626 0, /*tp_hash */ 627 0, /*tp_call*/ 628 salpy_str, /*tp_str*/ 629 0, /*tp_getattro*/ 630 0, /*tp_setattro*/ 631 0, /*tp_as_buffer*/ 632 Py_TPFLAGS_DEFAULT, /*tp_flags*/ 633 "GDB symtab_and_line object", /*tp_doc */ 634 0, /*tp_traverse */ 635 0, /*tp_clear */ 636 0, /*tp_richcompare */ 637 0, /*tp_weaklistoffset */ 638 0, /*tp_iter */ 639 0, /*tp_iternext */ 640 sal_object_methods, /*tp_methods */ 641 0, /*tp_members */ 642 sal_object_getset /*tp_getset */ 643 }; 644