1 /* Python interface to line tables. 2 3 Copyright (C) 2013-2015 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 "python-internal.h" 22 23 typedef struct { 24 PyObject_HEAD 25 /* The line table source line. */ 26 int line; 27 /* The pc associated with the source line. */ 28 CORE_ADDR pc; 29 } linetable_entry_object; 30 31 extern PyTypeObject linetable_entry_object_type 32 CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("linetable_entry_object"); 33 34 typedef struct { 35 PyObject_HEAD 36 /* The symtab python object. We store the Python object here as the 37 underlying symtab can become invalid, and we have to run validity 38 checks on it. */ 39 PyObject *symtab; 40 } linetable_object; 41 42 extern PyTypeObject linetable_object_type 43 CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("linetable_object"); 44 45 typedef struct { 46 PyObject_HEAD 47 /* The current entry in the line table for the iterator */ 48 int current_index; 49 /* Pointer back to the original source line table object. Needed to 50 check if the line table is still valid, and has not been invalidated 51 when an object file has been freed. */ 52 PyObject *source; 53 } ltpy_iterator_object; 54 55 extern PyTypeObject ltpy_iterator_object_type 56 CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("ltpy_iterator_object"); 57 58 /* Internal helper function to extract gdb.Symtab from a gdb.Linetable 59 object. */ 60 61 static PyObject * 62 get_symtab (PyObject *linetable) 63 { 64 linetable_object *lt = (linetable_object *) linetable; 65 66 return lt->symtab; 67 } 68 69 #define LTPY_REQUIRE_VALID(lt_obj, symtab) \ 70 do { \ 71 symtab = symtab_object_to_symtab (get_symtab (lt_obj)); \ 72 if (symtab == NULL) \ 73 { \ 74 PyErr_SetString (PyExc_RuntimeError, \ 75 _("Symbol Table in line table is invalid."));\ 76 return NULL; \ 77 } \ 78 } while (0) 79 80 81 /* Helper function to create a line table object that wraps a 82 gdb.Symtab object. */ 83 84 PyObject * 85 symtab_to_linetable_object (PyObject *symtab) 86 { 87 linetable_object *ltable; 88 89 ltable = PyObject_New (linetable_object, &linetable_object_type); 90 if (ltable != NULL) 91 { 92 ltable->symtab = symtab; 93 Py_INCREF (symtab); 94 } 95 return (PyObject *) ltable; 96 } 97 98 /* Internal helper function to build a line table object from a line 99 and an address. */ 100 101 static PyObject * 102 build_linetable_entry (int line, CORE_ADDR address) 103 { 104 linetable_entry_object *obj; 105 106 obj = PyObject_New (linetable_entry_object, 107 &linetable_entry_object_type); 108 if (obj != NULL) 109 { 110 obj->line = line; 111 obj->pc = address; 112 } 113 114 return (PyObject *) obj; 115 } 116 117 /* Internal helper function to build a Python Tuple from a GDB Vector. 118 A line table entry can have multiple PCs for a given source line. 119 Construct a Tuple of all entries for the given source line, LINE 120 from the line table VEC. Construct one line table entry object per 121 address. */ 122 123 static PyObject * 124 build_line_table_tuple_from_pcs (int line, VEC (CORE_ADDR) *vec) 125 { 126 int vec_len = 0; 127 PyObject *tuple; 128 CORE_ADDR pc; 129 int i; 130 131 vec_len = VEC_length (CORE_ADDR, vec); 132 if (vec_len < 1) 133 Py_RETURN_NONE; 134 135 tuple = PyTuple_New (vec_len); 136 137 if (tuple == NULL) 138 return NULL; 139 140 for (i = 0; VEC_iterate (CORE_ADDR, vec, i, pc); ++i) 141 { 142 PyObject *obj = build_linetable_entry (line, pc); 143 144 if (obj == NULL) 145 { 146 Py_DECREF (tuple); 147 tuple = NULL; 148 break; 149 } 150 else if (PyTuple_SetItem (tuple, i, obj) != 0) 151 { 152 Py_DECREF (obj); 153 Py_DECREF (tuple); 154 tuple = NULL; 155 break; 156 } 157 } 158 159 return tuple; 160 } 161 162 /* Implementation of gdb.LineTable.line (self) -> Tuple. Returns a 163 tuple of LineTableEntry objects associated with this line from the 164 in the line table. */ 165 166 static PyObject * 167 ltpy_get_pcs_for_line (PyObject *self, PyObject *args) 168 { 169 struct symtab *symtab; 170 gdb_py_longest py_line; 171 struct linetable_entry *best_entry = NULL; 172 linetable_entry_object *result; 173 VEC (CORE_ADDR) *pcs = NULL; 174 PyObject *tuple; 175 176 LTPY_REQUIRE_VALID (self, symtab); 177 178 if (! PyArg_ParseTuple (args, GDB_PY_LL_ARG, &py_line)) 179 return NULL; 180 181 TRY 182 { 183 pcs = find_pcs_for_symtab_line (symtab, py_line, &best_entry); 184 } 185 CATCH (except, RETURN_MASK_ALL) 186 { 187 GDB_PY_HANDLE_EXCEPTION (except); 188 } 189 END_CATCH 190 191 tuple = build_line_table_tuple_from_pcs (py_line, pcs); 192 VEC_free (CORE_ADDR, pcs); 193 194 return tuple; 195 } 196 197 /* Implementation of gdb.LineTable.has_line (self, line) -> Boolean. 198 Returns a Python Boolean indicating whether a source line has any 199 line table entries corresponding to it. */ 200 201 static PyObject * 202 ltpy_has_line (PyObject *self, PyObject *args) 203 { 204 struct symtab *symtab; 205 gdb_py_longest py_line; 206 int index; 207 208 LTPY_REQUIRE_VALID (self, symtab); 209 210 if (! PyArg_ParseTuple (args, GDB_PY_LL_ARG, &py_line)) 211 return NULL; 212 213 if (SYMTAB_LINETABLE (symtab) == NULL) 214 { 215 PyErr_SetString (PyExc_RuntimeError, 216 _("Linetable information not found in symbol table")); 217 return NULL; 218 } 219 220 for (index = 0; index < SYMTAB_LINETABLE (symtab)->nitems; index++) 221 { 222 struct linetable_entry *item = &(SYMTAB_LINETABLE (symtab)->item[index]); 223 if (item->line == py_line) 224 Py_RETURN_TRUE; 225 } 226 227 Py_RETURN_FALSE; 228 } 229 230 /* Implementation of gdb.LineTable.source_lines (self) -> FrozenSet. 231 Returns a Python FrozenSet that contains source line entries in the 232 line table. This function will just return the source lines 233 without corresponding addresses. */ 234 235 static PyObject * 236 ltpy_get_all_source_lines (PyObject *self, PyObject *args) 237 { 238 struct symtab *symtab; 239 Py_ssize_t index; 240 PyObject *source_list, *source_dict, *line; 241 struct linetable_entry *item; 242 Py_ssize_t list_size; 243 244 LTPY_REQUIRE_VALID (self, symtab); 245 246 if (SYMTAB_LINETABLE (symtab) == NULL) 247 { 248 PyErr_SetString (PyExc_RuntimeError, 249 _("Linetable information not found in symbol table")); 250 return NULL; 251 } 252 253 source_dict = PyDict_New (); 254 if (source_dict == NULL) 255 return NULL; 256 257 for (index = 0; index < SYMTAB_LINETABLE (symtab)->nitems; index++) 258 { 259 item = &(SYMTAB_LINETABLE (symtab)->item[index]); 260 261 /* 0 is used to signify end of line table information. Do not 262 include in the source set. */ 263 if (item->line > 0) 264 { 265 line = gdb_py_object_from_longest (item->line); 266 267 if (line == NULL) 268 { 269 Py_DECREF (source_dict); 270 return NULL; 271 } 272 273 if (PyDict_SetItem (source_dict, line, Py_None) == -1) 274 { 275 Py_DECREF (line); 276 Py_DECREF (source_dict); 277 return NULL; 278 } 279 280 Py_DECREF (line); 281 } 282 } 283 284 285 source_list = PyDict_Keys (source_dict); 286 Py_DECREF (source_dict); 287 288 return source_list; 289 } 290 291 /* Implementation of gdb.Linetable.is_valid (self) -> Boolean. 292 Returns True if this line table object still exists in GDB. */ 293 294 static PyObject * 295 ltpy_is_valid (PyObject *self, PyObject *args) 296 { 297 struct symtab *symtab = NULL; 298 linetable_object *obj = (linetable_object *) self; 299 300 symtab = symtab_object_to_symtab (get_symtab (self)); 301 302 if (symtab == NULL) 303 Py_RETURN_FALSE; 304 305 Py_RETURN_TRUE; 306 } 307 308 /* Deconstructor for the line table object. Decrement the reference 309 to the symbol table object before calling the default free. */ 310 311 static void 312 ltpy_dealloc (PyObject *self) 313 { 314 linetable_object *obj = (linetable_object *) self; 315 316 Py_DECREF (obj->symtab); 317 Py_TYPE (self)->tp_free (self); 318 } 319 320 /* Initialize LineTable, LineTableEntry and LineTableIterator 321 objects. */ 322 323 int 324 gdbpy_initialize_linetable (void) 325 { 326 if (PyType_Ready (&linetable_object_type) < 0) 327 return -1; 328 if (PyType_Ready (&linetable_entry_object_type) < 0) 329 return -1; 330 if (PyType_Ready (<py_iterator_object_type) < 0) 331 return -1; 332 333 Py_INCREF (&linetable_object_type); 334 Py_INCREF (&linetable_entry_object_type); 335 Py_INCREF (<py_iterator_object_type); 336 337 if (gdb_pymodule_addobject (gdb_module, "LineTable", 338 (PyObject *) &linetable_object_type) < 0) 339 return -1; 340 341 if (gdb_pymodule_addobject (gdb_module, "LineTableEntry", 342 (PyObject *) &linetable_entry_object_type) < 0) 343 return -1; 344 345 if (gdb_pymodule_addobject (gdb_module, "LineTableIterator", 346 (PyObject *) <py_iterator_object_type) < 0) 347 return -1; 348 349 return 0; 350 } 351 352 /* Linetable entry object get functions. */ 353 354 /* Implementation of gdb.LineTableEntry.line (self) -> Long. Returns 355 a long integer associated with the line table entry. */ 356 357 static PyObject * 358 ltpy_entry_get_line (PyObject *self, void *closure) 359 { 360 linetable_entry_object *obj = (linetable_entry_object *) self; 361 362 return gdb_py_object_from_longest (obj->line); 363 } 364 365 /* Implementation of gdb.LineTableEntry.pc (self) -> Long. Returns a 366 a long integer associated with the PC of the line table entry. */ 367 368 static PyObject * 369 ltpy_entry_get_pc (PyObject *self, void *closure) 370 { 371 linetable_entry_object *obj = (linetable_entry_object *) self; 372 373 return gdb_py_object_from_longest (obj->pc); 374 } 375 376 /* Linetable iterator functions. */ 377 378 /* Return a new line table iterator. */ 379 380 static PyObject * 381 ltpy_iter (PyObject *self) 382 { 383 ltpy_iterator_object *ltpy_iter_obj; 384 struct symtab *symtab = NULL; 385 386 LTPY_REQUIRE_VALID (self, symtab); 387 388 ltpy_iter_obj = PyObject_New (ltpy_iterator_object, 389 <py_iterator_object_type); 390 if (ltpy_iter_obj == NULL) 391 return NULL; 392 393 ltpy_iter_obj->current_index = 0; 394 ltpy_iter_obj->source = self; 395 396 Py_INCREF (self); 397 return (PyObject *) ltpy_iter_obj; 398 } 399 400 static void 401 ltpy_iterator_dealloc (PyObject *obj) 402 { 403 ltpy_iterator_object *iter_obj = (ltpy_iterator_object *) obj; 404 405 Py_DECREF (iter_obj->source); 406 } 407 408 /* Return a reference to the line table iterator. */ 409 410 static PyObject * 411 ltpy_iterator (PyObject *self) 412 { 413 ltpy_iterator_object *iter_obj = (ltpy_iterator_object *) self; 414 struct symtab *symtab; 415 416 LTPY_REQUIRE_VALID (iter_obj->source, symtab); 417 418 Py_INCREF (self); 419 return self; 420 } 421 422 /* Return the next line table entry in the iteration through the line 423 table data structure. */ 424 425 static PyObject * 426 ltpy_iternext (PyObject *self) 427 { 428 ltpy_iterator_object *iter_obj = (ltpy_iterator_object *) self; 429 struct symtab *symtab; 430 int index; 431 PyObject *obj; 432 struct linetable_entry *item; 433 434 LTPY_REQUIRE_VALID (iter_obj->source, symtab); 435 436 if (iter_obj->current_index >= SYMTAB_LINETABLE (symtab)->nitems) 437 goto stop_iteration; 438 439 item = &(SYMTAB_LINETABLE (symtab)->item[iter_obj->current_index]); 440 441 /* Skip over internal entries such as 0. 0 signifies the end of 442 line table data and is not useful to the API user. */ 443 while (item->line < 1) 444 { 445 iter_obj->current_index++; 446 447 /* Exit if the internal value is the last item in the line table. */ 448 if (iter_obj->current_index >= SYMTAB_LINETABLE (symtab)->nitems) 449 goto stop_iteration; 450 item = &(SYMTAB_LINETABLE (symtab)->item[iter_obj->current_index]); 451 } 452 453 obj = build_linetable_entry (item->line, item->pc); 454 iter_obj->current_index++; 455 456 return obj; 457 458 stop_iteration: 459 PyErr_SetNone (PyExc_StopIteration); 460 return NULL; 461 } 462 463 /* Implementation of gdb.LinetableIterator.is_valid (self) -> Boolean. 464 Returns True if this line table iterator object still exists in 465 GDB. */ 466 467 static PyObject * 468 ltpy_iter_is_valid (PyObject *self, PyObject *args) 469 { 470 struct symtab *symtab = NULL; 471 ltpy_iterator_object *iter_obj = (ltpy_iterator_object *) self; 472 473 symtab = symtab_object_to_symtab (get_symtab (iter_obj->source)); 474 475 if (symtab == NULL) 476 Py_RETURN_FALSE; 477 478 Py_RETURN_TRUE; 479 } 480 481 482 483 static PyMethodDef linetable_object_methods[] = { 484 { "line", ltpy_get_pcs_for_line, METH_VARARGS, 485 "line (lineno) -> Tuple\n\ 486 Return executable locations for a given source line." }, 487 { "has_line", ltpy_has_line, METH_VARARGS, 488 "has_line (lineno) -> Boolean\n\ 489 Return TRUE if this line has executable information, FALSE if not." }, 490 { "source_lines", ltpy_get_all_source_lines, METH_NOARGS, 491 "source_lines () -> FrozenSet\n\ 492 Return a frozen set of all executable source lines." }, 493 { "is_valid", ltpy_is_valid, METH_NOARGS, 494 "is_valid () -> Boolean.\n\ 495 Return True if this Linetable is valid, False if not." }, 496 {NULL} /* Sentinel */ 497 }; 498 499 PyTypeObject linetable_object_type = { 500 PyVarObject_HEAD_INIT (NULL, 0) 501 "gdb.LineTable", /*tp_name*/ 502 sizeof (linetable_object), /*tp_basicsize*/ 503 0, /*tp_itemsize*/ 504 ltpy_dealloc, /*tp_dealloc*/ 505 0, /*tp_print*/ 506 0, /*tp_getattr*/ 507 0, /*tp_setattr*/ 508 0, /*tp_compare*/ 509 0, /*tp_repr*/ 510 0, /*tp_as_number*/ 511 0, /*tp_as_sequence*/ 512 0, /*tp_as_mapping*/ 513 0, /*tp_hash */ 514 0, /*tp_call*/ 515 0, /*tp_str*/ 516 0, /*tp_getattro*/ 517 0, /*tp_setattro*/ 518 0, /*tp_as_buffer*/ 519 Py_TPFLAGS_DEFAULT, /*tp_flags*/ 520 "GDB line table object", /* tp_doc */ 521 0, /* tp_traverse */ 522 0, /* tp_clear */ 523 0, /* tp_richcompare */ 524 0, /* tp_weaklistoffset */ 525 ltpy_iter, /* tp_iter */ 526 0, /* tp_iternext */ 527 linetable_object_methods, /* tp_methods */ 528 0, /* tp_members */ 529 0, /* tp_getset */ 530 0, /* tp_base */ 531 0, /* tp_dict */ 532 0, /* tp_descr_get */ 533 0, /* tp_descr_set */ 534 0, /* tp_dictoffset */ 535 0, /* tp_init */ 536 0, /* tp_alloc */ 537 }; 538 539 static PyMethodDef ltpy_iterator_methods[] = { 540 { "is_valid", ltpy_iter_is_valid, METH_NOARGS, 541 "is_valid () -> Boolean.\n\ 542 Return True if this Linetable iterator is valid, False if not." }, 543 {NULL} /* Sentinel */ 544 }; 545 546 PyTypeObject ltpy_iterator_object_type = { 547 PyVarObject_HEAD_INIT (NULL, 0) 548 "gdb.LineTableIterator", /*tp_name*/ 549 sizeof (ltpy_iterator_object), /*tp_basicsize*/ 550 0, /*tp_itemsize*/ 551 ltpy_iterator_dealloc, /*tp_dealloc*/ 552 0, /*tp_print*/ 553 0, /*tp_getattr*/ 554 0, /*tp_setattr*/ 555 0, /*tp_compare*/ 556 0, /*tp_repr*/ 557 0, /*tp_as_number*/ 558 0, /*tp_as_sequence*/ 559 0, /*tp_as_mapping*/ 560 0, /*tp_hash */ 561 0, /*tp_call*/ 562 0, /*tp_str*/ 563 0, /*tp_getattro*/ 564 0, /*tp_setattro*/ 565 0, /*tp_as_buffer*/ 566 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_ITER, /*tp_flags*/ 567 "GDB line table iterator object", /*tp_doc */ 568 0, /*tp_traverse */ 569 0, /*tp_clear */ 570 0, /*tp_richcompare */ 571 0, /*tp_weaklistoffset */ 572 ltpy_iterator, /*tp_iter */ 573 ltpy_iternext, /*tp_iternext */ 574 ltpy_iterator_methods /*tp_methods */ 575 }; 576 577 578 static PyGetSetDef linetable_entry_object_getset[] = { 579 { "line", ltpy_entry_get_line, NULL, 580 "The line number in the source file.", NULL }, 581 { "pc", ltpy_entry_get_pc, NULL, 582 "The memory address for this line number.", NULL }, 583 { NULL } /* Sentinel */ 584 }; 585 586 PyTypeObject linetable_entry_object_type = { 587 PyVarObject_HEAD_INIT (NULL, 0) 588 "gdb.LineTableEntry", /*tp_name*/ 589 sizeof (linetable_entry_object), /*tp_basicsize*/ 590 0, /*tp_itemsize*/ 591 0, /*tp_dealloc*/ 592 0, /*tp_print*/ 593 0, /*tp_getattr*/ 594 0, /*tp_setattr*/ 595 0, /*tp_compare*/ 596 0, /*tp_repr*/ 597 0, /*tp_as_number*/ 598 0, /*tp_as_sequence*/ 599 0, /*tp_as_mapping*/ 600 0, /*tp_hash */ 601 0, /*tp_call*/ 602 0, /*tp_str*/ 603 0, /*tp_getattro*/ 604 0, /*tp_setattro*/ 605 0, /*tp_as_buffer*/ 606 Py_TPFLAGS_DEFAULT, /*tp_flags*/ 607 "GDB line table entry object", /* tp_doc */ 608 0, /* tp_traverse */ 609 0, /* tp_clear */ 610 0, /* tp_richcompare */ 611 0, /* tp_weaklistoffset */ 612 0, /* tp_iter */ 613 0, /* tp_iternext */ 614 0, /* tp_methods */ 615 0, /* tp_members */ 616 linetable_entry_object_getset, /* tp_getset */ 617 0, /* tp_base */ 618 0, /* tp_dict */ 619 0, /* tp_descr_get */ 620 0, /* tp_descr_set */ 621 0, /* tp_dictoffset */ 622 0, /* tp_init */ 623 0, /* tp_alloc */ 624 }; 625