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