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