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