1 /* Python interface to line tables.
3 Copyright (C) 2013-2018 Free Software Foundation, Inc.
5 This file is part of GDB.
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.
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.
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/>. */
21 #include "python-internal.h"
26 /* The line table source line. */
28 /* The pc associated with the source line. */
30 } linetable_entry_object
;
32 extern PyTypeObject linetable_entry_object_type
33 CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("linetable_entry_object");
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
43 extern PyTypeObject linetable_object_type
44 CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("linetable_object");
48 /* The current entry in the line table for the iterator */
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. */
54 } ltpy_iterator_object
;
56 extern PyTypeObject ltpy_iterator_object_type
57 CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("ltpy_iterator_object");
59 /* Internal helper function to extract gdb.Symtab from a gdb.LineTable
63 get_symtab (PyObject
*linetable
)
65 linetable_object
*lt
= (linetable_object
*) linetable
;
70 #define LTPY_REQUIRE_VALID(lt_obj, symtab) \
72 symtab = symtab_object_to_symtab (get_symtab (lt_obj)); \
75 PyErr_SetString (PyExc_RuntimeError, \
76 _("Symbol Table in line table is invalid."));\
82 /* Helper function to create a line table object that wraps a
86 symtab_to_linetable_object (PyObject
*symtab
)
88 linetable_object
*ltable
;
90 ltable
= PyObject_New (linetable_object
, &linetable_object_type
);
93 ltable
->symtab
= symtab
;
96 return (PyObject
*) ltable
;
99 /* Internal helper function to build a line table object from a line
103 build_linetable_entry (int line
, CORE_ADDR address
)
105 linetable_entry_object
*obj
;
107 obj
= PyObject_New (linetable_entry_object
,
108 &linetable_entry_object_type
);
115 return (PyObject
*) obj
;
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
125 build_line_table_tuple_from_pcs (int line
, const std::vector
<CORE_ADDR
> &pcs
)
132 gdbpy_ref
<> tuple (PyTuple_New (pcs
.size ()));
137 for (i
= 0; i
< pcs
.size (); ++i
)
139 CORE_ADDR pc
= pcs
[i
];
140 gdbpy_ref
<> obj (build_linetable_entry (line
, pc
));
144 else if (PyTuple_SetItem (tuple
.get (), i
, obj
.release ()) != 0)
148 return tuple
.release ();
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. */
156 ltpy_get_pcs_for_line (PyObject
*self
, PyObject
*args
)
158 struct symtab
*symtab
;
159 gdb_py_longest py_line
;
160 struct linetable_entry
*best_entry
= NULL
;
161 std::vector
<CORE_ADDR
> pcs
;
163 LTPY_REQUIRE_VALID (self
, symtab
);
165 if (! PyArg_ParseTuple (args
, GDB_PY_LL_ARG
, &py_line
))
170 pcs
= find_pcs_for_symtab_line (symtab
, py_line
, &best_entry
);
172 CATCH (except
, RETURN_MASK_ALL
)
174 GDB_PY_HANDLE_EXCEPTION (except
);
178 return build_line_table_tuple_from_pcs (py_line
, pcs
);
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. */
186 ltpy_has_line (PyObject
*self
, PyObject
*args
)
188 struct symtab
*symtab
;
189 gdb_py_longest py_line
;
192 LTPY_REQUIRE_VALID (self
, symtab
);
194 if (! PyArg_ParseTuple (args
, GDB_PY_LL_ARG
, &py_line
))
197 if (SYMTAB_LINETABLE (symtab
) == NULL
)
199 PyErr_SetString (PyExc_RuntimeError
,
200 _("Linetable information not found in symbol table"));
204 for (index
= 0; index
< SYMTAB_LINETABLE (symtab
)->nitems
; index
++)
206 struct linetable_entry
*item
= &(SYMTAB_LINETABLE (symtab
)->item
[index
]);
207 if (item
->line
== py_line
)
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. */
220 ltpy_get_all_source_lines (PyObject
*self
, PyObject
*args
)
222 struct symtab
*symtab
;
224 struct linetable_entry
*item
;
226 LTPY_REQUIRE_VALID (self
, symtab
);
228 if (SYMTAB_LINETABLE (symtab
) == NULL
)
230 PyErr_SetString (PyExc_RuntimeError
,
231 _("Linetable information not found in symbol table"));
235 gdbpy_ref
<> source_dict (PyDict_New ());
236 if (source_dict
== NULL
)
239 for (index
= 0; index
< SYMTAB_LINETABLE (symtab
)->nitems
; index
++)
241 item
= &(SYMTAB_LINETABLE (symtab
)->item
[index
]);
243 /* 0 is used to signify end of line table information. Do not
244 include in the source set. */
247 gdbpy_ref
<> line (gdb_py_object_from_longest (item
->line
));
252 if (PyDict_SetItem (source_dict
.get (), line
.get (), Py_None
) == -1)
257 return PyDict_Keys (source_dict
.get ());
260 /* Implementation of gdb.LineTable.is_valid (self) -> Boolean.
261 Returns True if this line table object still exists in GDB. */
264 ltpy_is_valid (PyObject
*self
, PyObject
*args
)
266 struct symtab
*symtab
= NULL
;
268 symtab
= symtab_object_to_symtab (get_symtab (self
));
276 /* Deconstructor for the line table object. Decrement the reference
277 to the symbol table object before calling the default free. */
280 ltpy_dealloc (PyObject
*self
)
282 linetable_object
*obj
= (linetable_object
*) self
;
284 Py_DECREF (obj
->symtab
);
285 Py_TYPE (self
)->tp_free (self
);
288 /* Initialize LineTable, LineTableEntry and LineTableIterator
292 gdbpy_initialize_linetable (void)
294 if (PyType_Ready (&linetable_object_type
) < 0)
296 if (PyType_Ready (&linetable_entry_object_type
) < 0)
298 if (PyType_Ready (<py_iterator_object_type
) < 0)
301 Py_INCREF (&linetable_object_type
);
302 Py_INCREF (&linetable_entry_object_type
);
303 Py_INCREF (<py_iterator_object_type
);
305 if (gdb_pymodule_addobject (gdb_module
, "LineTable",
306 (PyObject
*) &linetable_object_type
) < 0)
309 if (gdb_pymodule_addobject (gdb_module
, "LineTableEntry",
310 (PyObject
*) &linetable_entry_object_type
) < 0)
313 if (gdb_pymodule_addobject (gdb_module
, "LineTableIterator",
314 (PyObject
*) <py_iterator_object_type
) < 0)
320 /* LineTable entry object get functions. */
322 /* Implementation of gdb.LineTableEntry.line (self) -> Long. Returns
323 a long integer associated with the line table entry. */
326 ltpy_entry_get_line (PyObject
*self
, void *closure
)
328 linetable_entry_object
*obj
= (linetable_entry_object
*) self
;
330 return gdb_py_object_from_longest (obj
->line
);
333 /* Implementation of gdb.LineTableEntry.pc (self) -> Long. Returns a
334 a long integer associated with the PC of the line table entry. */
337 ltpy_entry_get_pc (PyObject
*self
, void *closure
)
339 linetable_entry_object
*obj
= (linetable_entry_object
*) self
;
341 return gdb_py_object_from_longest (obj
->pc
);
344 /* LineTable iterator functions. */
346 /* Return a new line table iterator. */
349 ltpy_iter (PyObject
*self
)
351 ltpy_iterator_object
*ltpy_iter_obj
;
352 struct symtab
*symtab
= NULL
;
354 LTPY_REQUIRE_VALID (self
, symtab
);
356 ltpy_iter_obj
= PyObject_New (ltpy_iterator_object
,
357 <py_iterator_object_type
);
358 if (ltpy_iter_obj
== NULL
)
361 ltpy_iter_obj
->current_index
= 0;
362 ltpy_iter_obj
->source
= self
;
365 return (PyObject
*) ltpy_iter_obj
;
369 ltpy_iterator_dealloc (PyObject
*obj
)
371 ltpy_iterator_object
*iter_obj
= (ltpy_iterator_object
*) obj
;
373 Py_DECREF (iter_obj
->source
);
376 /* Return a reference to the line table iterator. */
379 ltpy_iterator (PyObject
*self
)
381 ltpy_iterator_object
*iter_obj
= (ltpy_iterator_object
*) self
;
382 struct symtab
*symtab
;
384 LTPY_REQUIRE_VALID (iter_obj
->source
, symtab
);
390 /* Return the next line table entry in the iteration through the line
391 table data structure. */
394 ltpy_iternext (PyObject
*self
)
396 ltpy_iterator_object
*iter_obj
= (ltpy_iterator_object
*) self
;
397 struct symtab
*symtab
;
399 struct linetable_entry
*item
;
401 LTPY_REQUIRE_VALID (iter_obj
->source
, symtab
);
403 if (iter_obj
->current_index
>= SYMTAB_LINETABLE (symtab
)->nitems
)
405 PyErr_SetNone (PyExc_StopIteration
);
409 item
= &(SYMTAB_LINETABLE (symtab
)->item
[iter_obj
->current_index
]);
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)
415 iter_obj
->current_index
++;
417 /* Exit if the internal value is the last item in the line table. */
418 if (iter_obj
->current_index
>= SYMTAB_LINETABLE (symtab
)->nitems
)
420 PyErr_SetNone (PyExc_StopIteration
);
423 item
= &(SYMTAB_LINETABLE (symtab
)->item
[iter_obj
->current_index
]);
426 obj
= build_linetable_entry (item
->line
, item
->pc
);
427 iter_obj
->current_index
++;
432 /* Implementation of gdb.LineTableIterator.is_valid (self) -> Boolean.
433 Returns True if this line table iterator object still exists in
437 ltpy_iter_is_valid (PyObject
*self
, PyObject
*args
)
439 struct symtab
*symtab
= NULL
;
440 ltpy_iterator_object
*iter_obj
= (ltpy_iterator_object
*) self
;
442 symtab
= symtab_object_to_symtab (get_symtab (iter_obj
->source
));
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 */
468 PyTypeObject linetable_object_type
= {
469 PyVarObject_HEAD_INIT (NULL
, 0)
470 "gdb.LineTable", /*tp_name*/
471 sizeof (linetable_object
), /*tp_basicsize*/
473 ltpy_dealloc
, /*tp_dealloc*/
480 0, /*tp_as_sequence*/
488 Py_TPFLAGS_DEFAULT
, /*tp_flags*/
489 "GDB line table object", /* tp_doc */
492 0, /* tp_richcompare */
493 0, /* tp_weaklistoffset */
494 ltpy_iter
, /* tp_iter */
496 linetable_object_methods
, /* tp_methods */
501 0, /* tp_descr_get */
502 0, /* tp_descr_set */
503 0, /* tp_dictoffset */
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 */
515 PyTypeObject ltpy_iterator_object_type
= {
516 PyVarObject_HEAD_INIT (NULL
, 0)
517 "gdb.LineTableIterator", /*tp_name*/
518 sizeof (ltpy_iterator_object
), /*tp_basicsize*/
520 ltpy_iterator_dealloc
, /*tp_dealloc*/
527 0, /*tp_as_sequence*/
535 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_ITER
, /*tp_flags*/
536 "GDB line table iterator object", /*tp_doc */
539 0, /*tp_richcompare */
540 0, /*tp_weaklistoffset */
541 ltpy_iterator
, /*tp_iter */
542 ltpy_iternext
, /*tp_iternext */
543 ltpy_iterator_methods
/*tp_methods */
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 */
555 PyTypeObject linetable_entry_object_type
= {
556 PyVarObject_HEAD_INIT (NULL
, 0)
557 "gdb.LineTableEntry", /*tp_name*/
558 sizeof (linetable_entry_object
), /*tp_basicsize*/
567 0, /*tp_as_sequence*/
575 Py_TPFLAGS_DEFAULT
, /*tp_flags*/
576 "GDB line table entry object", /* tp_doc */
579 0, /* tp_richcompare */
580 0, /* tp_weaklistoffset */
585 linetable_entry_object_getset
, /* tp_getset */
588 0, /* tp_descr_get */
589 0, /* tp_descr_set */
590 0, /* tp_dictoffset */