1 /* Python interface to line tables. 2 3 Copyright (C) 2013-2016 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 VEC (CORE_ADDR) *pcs = NULL; 173 PyObject *tuple; 174 175 LTPY_REQUIRE_VALID (self, symtab); 176 177 if (! PyArg_ParseTuple (args, GDB_PY_LL_ARG, &py_line)) 178 return NULL; 179 180 TRY 181 { 182 pcs = find_pcs_for_symtab_line (symtab, py_line, &best_entry); 183 } 184 CATCH (except, RETURN_MASK_ALL) 185 { 186 GDB_PY_HANDLE_EXCEPTION (except); 187 } 188 END_CATCH 189 190 tuple = build_line_table_tuple_from_pcs (py_line, pcs); 191 VEC_free (CORE_ADDR, pcs); 192 193 return tuple; 194 } 195 196 /* Implementation of gdb.LineTable.has_line (self, line) -> Boolean. 197 Returns a Python Boolean indicating whether a source line has any 198 line table entries corresponding to it. */ 199 200 static PyObject * 201 ltpy_has_line (PyObject *self, PyObject *args) 202 { 203 struct symtab *symtab; 204 gdb_py_longest py_line; 205 int index; 206 207 LTPY_REQUIRE_VALID (self, symtab); 208 209 if (! PyArg_ParseTuple (args, GDB_PY_LL_ARG, &py_line)) 210 return NULL; 211 212 if (SYMTAB_LINETABLE (symtab) == NULL) 213 { 214 PyErr_SetString (PyExc_RuntimeError, 215 _("Linetable information not found in symbol table")); 216 return NULL; 217 } 218 219 for (index = 0; index < SYMTAB_LINETABLE (symtab)->nitems; index++) 220 { 221 struct linetable_entry *item = &(SYMTAB_LINETABLE (symtab)->item[index]); 222 if (item->line == py_line) 223 Py_RETURN_TRUE; 224 } 225 226 Py_RETURN_FALSE; 227 } 228 229 /* Implementation of gdb.LineTable.source_lines (self) -> List. 230 Returns a Python List that contains source line entries in the 231 line table. This function will just return the source lines 232 without corresponding addresses. */ 233 234 static PyObject * 235 ltpy_get_all_source_lines (PyObject *self, PyObject *args) 236 { 237 struct symtab *symtab; 238 Py_ssize_t index; 239 PyObject *source_list, *source_dict, *line; 240 struct linetable_entry *item; 241 242 LTPY_REQUIRE_VALID (self, symtab); 243 244 if (SYMTAB_LINETABLE (symtab) == NULL) 245 { 246 PyErr_SetString (PyExc_RuntimeError, 247 _("Linetable information not found in symbol table")); 248 return NULL; 249 } 250 251 source_dict = PyDict_New (); 252 if (source_dict == NULL) 253 return NULL; 254 255 for (index = 0; index < SYMTAB_LINETABLE (symtab)->nitems; index++) 256 { 257 item = &(SYMTAB_LINETABLE (symtab)->item[index]); 258 259 /* 0 is used to signify end of line table information. Do not 260 include in the source set. */ 261 if (item->line > 0) 262 { 263 line = gdb_py_object_from_longest (item->line); 264 265 if (line == NULL) 266 { 267 Py_DECREF (source_dict); 268 return NULL; 269 } 270 271 if (PyDict_SetItem (source_dict, line, Py_None) == -1) 272 { 273 Py_DECREF (line); 274 Py_DECREF (source_dict); 275 return NULL; 276 } 277 278 Py_DECREF (line); 279 } 280 } 281 282 283 source_list = PyDict_Keys (source_dict); 284 Py_DECREF (source_dict); 285 286 return source_list; 287 } 288 289 /* Implementation of gdb.LineTable.is_valid (self) -> Boolean. 290 Returns True if this line table object still exists in GDB. */ 291 292 static PyObject * 293 ltpy_is_valid (PyObject *self, PyObject *args) 294 { 295 struct symtab *symtab = NULL; 296 297 symtab = symtab_object_to_symtab (get_symtab (self)); 298 299 if (symtab == NULL) 300 Py_RETURN_FALSE; 301 302 Py_RETURN_TRUE; 303 } 304 305 /* Deconstructor for the line table object. Decrement the reference 306 to the symbol table object before calling the default free. */ 307 308 static void 309 ltpy_dealloc (PyObject *self) 310 { 311 linetable_object *obj = (linetable_object *) self; 312 313 Py_DECREF (obj->symtab); 314 Py_TYPE (self)->tp_free (self); 315 } 316 317 /* Initialize LineTable, LineTableEntry and LineTableIterator 318 objects. */ 319 320 int 321 gdbpy_initialize_linetable (void) 322 { 323 if (PyType_Ready (&linetable_object_type) < 0) 324 return -1; 325 if (PyType_Ready (&linetable_entry_object_type) < 0) 326 return -1; 327 if (PyType_Ready (<py_iterator_object_type) < 0) 328 return -1; 329 330 Py_INCREF (&linetable_object_type); 331 Py_INCREF (&linetable_entry_object_type); 332 Py_INCREF (<py_iterator_object_type); 333 334 if (gdb_pymodule_addobject (gdb_module, "LineTable", 335 (PyObject *) &linetable_object_type) < 0) 336 return -1; 337 338 if (gdb_pymodule_addobject (gdb_module, "LineTableEntry", 339 (PyObject *) &linetable_entry_object_type) < 0) 340 return -1; 341 342 if (gdb_pymodule_addobject (gdb_module, "LineTableIterator", 343 (PyObject *) <py_iterator_object_type) < 0) 344 return -1; 345 346 return 0; 347 } 348 349 /* LineTable entry object get functions. */ 350 351 /* Implementation of gdb.LineTableEntry.line (self) -> Long. Returns 352 a long integer associated with the line table entry. */ 353 354 static PyObject * 355 ltpy_entry_get_line (PyObject *self, void *closure) 356 { 357 linetable_entry_object *obj = (linetable_entry_object *) self; 358 359 return gdb_py_object_from_longest (obj->line); 360 } 361 362 /* Implementation of gdb.LineTableEntry.pc (self) -> Long. Returns a 363 a long integer associated with the PC of the line table entry. */ 364 365 static PyObject * 366 ltpy_entry_get_pc (PyObject *self, void *closure) 367 { 368 linetable_entry_object *obj = (linetable_entry_object *) self; 369 370 return gdb_py_object_from_longest (obj->pc); 371 } 372 373 /* LineTable iterator functions. */ 374 375 /* Return a new line table iterator. */ 376 377 static PyObject * 378 ltpy_iter (PyObject *self) 379 { 380 ltpy_iterator_object *ltpy_iter_obj; 381 struct symtab *symtab = NULL; 382 383 LTPY_REQUIRE_VALID (self, symtab); 384 385 ltpy_iter_obj = PyObject_New (ltpy_iterator_object, 386 <py_iterator_object_type); 387 if (ltpy_iter_obj == NULL) 388 return NULL; 389 390 ltpy_iter_obj->current_index = 0; 391 ltpy_iter_obj->source = self; 392 393 Py_INCREF (self); 394 return (PyObject *) ltpy_iter_obj; 395 } 396 397 static void 398 ltpy_iterator_dealloc (PyObject *obj) 399 { 400 ltpy_iterator_object *iter_obj = (ltpy_iterator_object *) obj; 401 402 Py_DECREF (iter_obj->source); 403 } 404 405 /* Return a reference to the line table iterator. */ 406 407 static PyObject * 408 ltpy_iterator (PyObject *self) 409 { 410 ltpy_iterator_object *iter_obj = (ltpy_iterator_object *) self; 411 struct symtab *symtab; 412 413 LTPY_REQUIRE_VALID (iter_obj->source, symtab); 414 415 Py_INCREF (self); 416 return self; 417 } 418 419 /* Return the next line table entry in the iteration through the line 420 table data structure. */ 421 422 static PyObject * 423 ltpy_iternext (PyObject *self) 424 { 425 ltpy_iterator_object *iter_obj = (ltpy_iterator_object *) self; 426 struct symtab *symtab; 427 PyObject *obj; 428 struct linetable_entry *item; 429 430 LTPY_REQUIRE_VALID (iter_obj->source, symtab); 431 432 if (iter_obj->current_index >= SYMTAB_LINETABLE (symtab)->nitems) 433 goto stop_iteration; 434 435 item = &(SYMTAB_LINETABLE (symtab)->item[iter_obj->current_index]); 436 437 /* Skip over internal entries such as 0. 0 signifies the end of 438 line table data and is not useful to the API user. */ 439 while (item->line < 1) 440 { 441 iter_obj->current_index++; 442 443 /* Exit if the internal value is the last item in the line table. */ 444 if (iter_obj->current_index >= SYMTAB_LINETABLE (symtab)->nitems) 445 goto stop_iteration; 446 item = &(SYMTAB_LINETABLE (symtab)->item[iter_obj->current_index]); 447 } 448 449 obj = build_linetable_entry (item->line, item->pc); 450 iter_obj->current_index++; 451 452 return obj; 453 454 stop_iteration: 455 PyErr_SetNone (PyExc_StopIteration); 456 return NULL; 457 } 458 459 /* Implementation of gdb.LineTableIterator.is_valid (self) -> Boolean. 460 Returns True if this line table iterator object still exists in 461 GDB. */ 462 463 static PyObject * 464 ltpy_iter_is_valid (PyObject *self, PyObject *args) 465 { 466 struct symtab *symtab = NULL; 467 ltpy_iterator_object *iter_obj = (ltpy_iterator_object *) self; 468 469 symtab = symtab_object_to_symtab (get_symtab (iter_obj->source)); 470 471 if (symtab == NULL) 472 Py_RETURN_FALSE; 473 474 Py_RETURN_TRUE; 475 } 476 477 478 479 static PyMethodDef linetable_object_methods[] = { 480 { "line", ltpy_get_pcs_for_line, METH_VARARGS, 481 "line (lineno) -> Tuple\n\ 482 Return executable locations for a given source line." }, 483 { "has_line", ltpy_has_line, METH_VARARGS, 484 "has_line (lineno) -> Boolean\n\ 485 Return TRUE if this line has executable information, FALSE if not." }, 486 { "source_lines", ltpy_get_all_source_lines, METH_NOARGS, 487 "source_lines () -> List\n\ 488 Return a list of all executable source lines." }, 489 { "is_valid", ltpy_is_valid, METH_NOARGS, 490 "is_valid () -> Boolean.\n\ 491 Return True if this LineTable is valid, False if not." }, 492 {NULL} /* Sentinel */ 493 }; 494 495 PyTypeObject linetable_object_type = { 496 PyVarObject_HEAD_INIT (NULL, 0) 497 "gdb.LineTable", /*tp_name*/ 498 sizeof (linetable_object), /*tp_basicsize*/ 499 0, /*tp_itemsize*/ 500 ltpy_dealloc, /*tp_dealloc*/ 501 0, /*tp_print*/ 502 0, /*tp_getattr*/ 503 0, /*tp_setattr*/ 504 0, /*tp_compare*/ 505 0, /*tp_repr*/ 506 0, /*tp_as_number*/ 507 0, /*tp_as_sequence*/ 508 0, /*tp_as_mapping*/ 509 0, /*tp_hash */ 510 0, /*tp_call*/ 511 0, /*tp_str*/ 512 0, /*tp_getattro*/ 513 0, /*tp_setattro*/ 514 0, /*tp_as_buffer*/ 515 Py_TPFLAGS_DEFAULT, /*tp_flags*/ 516 "GDB line table object", /* tp_doc */ 517 0, /* tp_traverse */ 518 0, /* tp_clear */ 519 0, /* tp_richcompare */ 520 0, /* tp_weaklistoffset */ 521 ltpy_iter, /* tp_iter */ 522 0, /* tp_iternext */ 523 linetable_object_methods, /* tp_methods */ 524 0, /* tp_members */ 525 0, /* tp_getset */ 526 0, /* tp_base */ 527 0, /* tp_dict */ 528 0, /* tp_descr_get */ 529 0, /* tp_descr_set */ 530 0, /* tp_dictoffset */ 531 0, /* tp_init */ 532 0, /* tp_alloc */ 533 }; 534 535 static PyMethodDef ltpy_iterator_methods[] = { 536 { "is_valid", ltpy_iter_is_valid, METH_NOARGS, 537 "is_valid () -> Boolean.\n\ 538 Return True if this LineTable iterator is valid, False if not." }, 539 {NULL} /* Sentinel */ 540 }; 541 542 PyTypeObject ltpy_iterator_object_type = { 543 PyVarObject_HEAD_INIT (NULL, 0) 544 "gdb.LineTableIterator", /*tp_name*/ 545 sizeof (ltpy_iterator_object), /*tp_basicsize*/ 546 0, /*tp_itemsize*/ 547 ltpy_iterator_dealloc, /*tp_dealloc*/ 548 0, /*tp_print*/ 549 0, /*tp_getattr*/ 550 0, /*tp_setattr*/ 551 0, /*tp_compare*/ 552 0, /*tp_repr*/ 553 0, /*tp_as_number*/ 554 0, /*tp_as_sequence*/ 555 0, /*tp_as_mapping*/ 556 0, /*tp_hash */ 557 0, /*tp_call*/ 558 0, /*tp_str*/ 559 0, /*tp_getattro*/ 560 0, /*tp_setattro*/ 561 0, /*tp_as_buffer*/ 562 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_ITER, /*tp_flags*/ 563 "GDB line table iterator object", /*tp_doc */ 564 0, /*tp_traverse */ 565 0, /*tp_clear */ 566 0, /*tp_richcompare */ 567 0, /*tp_weaklistoffset */ 568 ltpy_iterator, /*tp_iter */ 569 ltpy_iternext, /*tp_iternext */ 570 ltpy_iterator_methods /*tp_methods */ 571 }; 572 573 574 static PyGetSetDef linetable_entry_object_getset[] = { 575 { "line", ltpy_entry_get_line, NULL, 576 "The line number in the source file.", NULL }, 577 { "pc", ltpy_entry_get_pc, NULL, 578 "The memory address for this line number.", NULL }, 579 { NULL } /* Sentinel */ 580 }; 581 582 PyTypeObject linetable_entry_object_type = { 583 PyVarObject_HEAD_INIT (NULL, 0) 584 "gdb.LineTableEntry", /*tp_name*/ 585 sizeof (linetable_entry_object), /*tp_basicsize*/ 586 0, /*tp_itemsize*/ 587 0, /*tp_dealloc*/ 588 0, /*tp_print*/ 589 0, /*tp_getattr*/ 590 0, /*tp_setattr*/ 591 0, /*tp_compare*/ 592 0, /*tp_repr*/ 593 0, /*tp_as_number*/ 594 0, /*tp_as_sequence*/ 595 0, /*tp_as_mapping*/ 596 0, /*tp_hash */ 597 0, /*tp_call*/ 598 0, /*tp_str*/ 599 0, /*tp_getattro*/ 600 0, /*tp_setattro*/ 601 0, /*tp_as_buffer*/ 602 Py_TPFLAGS_DEFAULT, /*tp_flags*/ 603 "GDB line table entry object", /* tp_doc */ 604 0, /* tp_traverse */ 605 0, /* tp_clear */ 606 0, /* tp_richcompare */ 607 0, /* tp_weaklistoffset */ 608 0, /* tp_iter */ 609 0, /* tp_iternext */ 610 0, /* tp_methods */ 611 0, /* tp_members */ 612 linetable_entry_object_getset, /* tp_getset */ 613 0, /* tp_base */ 614 0, /* tp_dict */ 615 0, /* tp_descr_get */ 616 0, /* tp_descr_set */ 617 0, /* tp_dictoffset */ 618 0, /* tp_init */ 619 0, /* tp_alloc */ 620 }; 621