1 /* Python interface to line tables.
3 Copyright (C) 2013-2017 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 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
125 build_line_table_tuple_from_pcs (int line
, VEC (CORE_ADDR
) *vec
)
131 vec_len
= VEC_length (CORE_ADDR
, vec
);
135 gdbpy_ref
<> tuple (PyTuple_New (vec_len
));
140 for (i
= 0; VEC_iterate (CORE_ADDR
, vec
, i
, pc
); ++i
)
142 gdbpy_ref
<> obj (build_linetable_entry (line
, pc
));
146 else if (PyTuple_SetItem (tuple
.get (), i
, obj
.release ()) != 0)
150 return tuple
.release ();
153 /* Implementation of gdb.LineTable.line (self) -> Tuple. Returns a
154 tuple of LineTableEntry objects associated with this line from the
155 in the line table. */
158 ltpy_get_pcs_for_line (PyObject
*self
, PyObject
*args
)
160 struct symtab
*symtab
;
161 gdb_py_longest py_line
;
162 struct linetable_entry
*best_entry
= NULL
;
163 VEC (CORE_ADDR
) *pcs
= NULL
;
166 LTPY_REQUIRE_VALID (self
, symtab
);
168 if (! PyArg_ParseTuple (args
, GDB_PY_LL_ARG
, &py_line
))
173 pcs
= find_pcs_for_symtab_line (symtab
, py_line
, &best_entry
);
175 CATCH (except
, RETURN_MASK_ALL
)
177 GDB_PY_HANDLE_EXCEPTION (except
);
181 tuple
= build_line_table_tuple_from_pcs (py_line
, pcs
);
182 VEC_free (CORE_ADDR
, pcs
);
187 /* Implementation of gdb.LineTable.has_line (self, line) -> Boolean.
188 Returns a Python Boolean indicating whether a source line has any
189 line table entries corresponding to it. */
192 ltpy_has_line (PyObject
*self
, PyObject
*args
)
194 struct symtab
*symtab
;
195 gdb_py_longest py_line
;
198 LTPY_REQUIRE_VALID (self
, symtab
);
200 if (! PyArg_ParseTuple (args
, GDB_PY_LL_ARG
, &py_line
))
203 if (SYMTAB_LINETABLE (symtab
) == NULL
)
205 PyErr_SetString (PyExc_RuntimeError
,
206 _("Linetable information not found in symbol table"));
210 for (index
= 0; index
< SYMTAB_LINETABLE (symtab
)->nitems
; index
++)
212 struct linetable_entry
*item
= &(SYMTAB_LINETABLE (symtab
)->item
[index
]);
213 if (item
->line
== py_line
)
220 /* Implementation of gdb.LineTable.source_lines (self) -> List.
221 Returns a Python List that contains source line entries in the
222 line table. This function will just return the source lines
223 without corresponding addresses. */
226 ltpy_get_all_source_lines (PyObject
*self
, PyObject
*args
)
228 struct symtab
*symtab
;
230 struct linetable_entry
*item
;
232 LTPY_REQUIRE_VALID (self
, symtab
);
234 if (SYMTAB_LINETABLE (symtab
) == NULL
)
236 PyErr_SetString (PyExc_RuntimeError
,
237 _("Linetable information not found in symbol table"));
241 gdbpy_ref
<> source_dict (PyDict_New ());
242 if (source_dict
== NULL
)
245 for (index
= 0; index
< SYMTAB_LINETABLE (symtab
)->nitems
; index
++)
247 item
= &(SYMTAB_LINETABLE (symtab
)->item
[index
]);
249 /* 0 is used to signify end of line table information. Do not
250 include in the source set. */
253 gdbpy_ref
<> line (gdb_py_object_from_longest (item
->line
));
258 if (PyDict_SetItem (source_dict
.get (), line
.get (), Py_None
) == -1)
263 return PyDict_Keys (source_dict
.get ());
266 /* Implementation of gdb.LineTable.is_valid (self) -> Boolean.
267 Returns True if this line table object still exists in GDB. */
270 ltpy_is_valid (PyObject
*self
, PyObject
*args
)
272 struct symtab
*symtab
= NULL
;
274 symtab
= symtab_object_to_symtab (get_symtab (self
));
282 /* Deconstructor for the line table object. Decrement the reference
283 to the symbol table object before calling the default free. */
286 ltpy_dealloc (PyObject
*self
)
288 linetable_object
*obj
= (linetable_object
*) self
;
290 Py_DECREF (obj
->symtab
);
291 Py_TYPE (self
)->tp_free (self
);
294 /* Initialize LineTable, LineTableEntry and LineTableIterator
298 gdbpy_initialize_linetable (void)
300 if (PyType_Ready (&linetable_object_type
) < 0)
302 if (PyType_Ready (&linetable_entry_object_type
) < 0)
304 if (PyType_Ready (<py_iterator_object_type
) < 0)
307 Py_INCREF (&linetable_object_type
);
308 Py_INCREF (&linetable_entry_object_type
);
309 Py_INCREF (<py_iterator_object_type
);
311 if (gdb_pymodule_addobject (gdb_module
, "LineTable",
312 (PyObject
*) &linetable_object_type
) < 0)
315 if (gdb_pymodule_addobject (gdb_module
, "LineTableEntry",
316 (PyObject
*) &linetable_entry_object_type
) < 0)
319 if (gdb_pymodule_addobject (gdb_module
, "LineTableIterator",
320 (PyObject
*) <py_iterator_object_type
) < 0)
326 /* LineTable entry object get functions. */
328 /* Implementation of gdb.LineTableEntry.line (self) -> Long. Returns
329 a long integer associated with the line table entry. */
332 ltpy_entry_get_line (PyObject
*self
, void *closure
)
334 linetable_entry_object
*obj
= (linetable_entry_object
*) self
;
336 return gdb_py_object_from_longest (obj
->line
);
339 /* Implementation of gdb.LineTableEntry.pc (self) -> Long. Returns a
340 a long integer associated with the PC of the line table entry. */
343 ltpy_entry_get_pc (PyObject
*self
, void *closure
)
345 linetable_entry_object
*obj
= (linetable_entry_object
*) self
;
347 return gdb_py_object_from_longest (obj
->pc
);
350 /* LineTable iterator functions. */
352 /* Return a new line table iterator. */
355 ltpy_iter (PyObject
*self
)
357 ltpy_iterator_object
*ltpy_iter_obj
;
358 struct symtab
*symtab
= NULL
;
360 LTPY_REQUIRE_VALID (self
, symtab
);
362 ltpy_iter_obj
= PyObject_New (ltpy_iterator_object
,
363 <py_iterator_object_type
);
364 if (ltpy_iter_obj
== NULL
)
367 ltpy_iter_obj
->current_index
= 0;
368 ltpy_iter_obj
->source
= self
;
371 return (PyObject
*) ltpy_iter_obj
;
375 ltpy_iterator_dealloc (PyObject
*obj
)
377 ltpy_iterator_object
*iter_obj
= (ltpy_iterator_object
*) obj
;
379 Py_DECREF (iter_obj
->source
);
382 /* Return a reference to the line table iterator. */
385 ltpy_iterator (PyObject
*self
)
387 ltpy_iterator_object
*iter_obj
= (ltpy_iterator_object
*) self
;
388 struct symtab
*symtab
;
390 LTPY_REQUIRE_VALID (iter_obj
->source
, symtab
);
396 /* Return the next line table entry in the iteration through the line
397 table data structure. */
400 ltpy_iternext (PyObject
*self
)
402 ltpy_iterator_object
*iter_obj
= (ltpy_iterator_object
*) self
;
403 struct symtab
*symtab
;
405 struct linetable_entry
*item
;
407 LTPY_REQUIRE_VALID (iter_obj
->source
, symtab
);
409 if (iter_obj
->current_index
>= SYMTAB_LINETABLE (symtab
)->nitems
)
411 PyErr_SetNone (PyExc_StopIteration
);
415 item
= &(SYMTAB_LINETABLE (symtab
)->item
[iter_obj
->current_index
]);
417 /* Skip over internal entries such as 0. 0 signifies the end of
418 line table data and is not useful to the API user. */
419 while (item
->line
< 1)
421 iter_obj
->current_index
++;
423 /* Exit if the internal value is the last item in the line table. */
424 if (iter_obj
->current_index
>= SYMTAB_LINETABLE (symtab
)->nitems
)
426 PyErr_SetNone (PyExc_StopIteration
);
429 item
= &(SYMTAB_LINETABLE (symtab
)->item
[iter_obj
->current_index
]);
432 obj
= build_linetable_entry (item
->line
, item
->pc
);
433 iter_obj
->current_index
++;
438 /* Implementation of gdb.LineTableIterator.is_valid (self) -> Boolean.
439 Returns True if this line table iterator object still exists in
443 ltpy_iter_is_valid (PyObject
*self
, PyObject
*args
)
445 struct symtab
*symtab
= NULL
;
446 ltpy_iterator_object
*iter_obj
= (ltpy_iterator_object
*) self
;
448 symtab
= symtab_object_to_symtab (get_symtab (iter_obj
->source
));
458 static PyMethodDef linetable_object_methods
[] = {
459 { "line", ltpy_get_pcs_for_line
, METH_VARARGS
,
460 "line (lineno) -> Tuple\n\
461 Return executable locations for a given source line." },
462 { "has_line", ltpy_has_line
, METH_VARARGS
,
463 "has_line (lineno) -> Boolean\n\
464 Return TRUE if this line has executable information, FALSE if not." },
465 { "source_lines", ltpy_get_all_source_lines
, METH_NOARGS
,
466 "source_lines () -> List\n\
467 Return a list of all executable source lines." },
468 { "is_valid", ltpy_is_valid
, METH_NOARGS
,
469 "is_valid () -> Boolean.\n\
470 Return True if this LineTable is valid, False if not." },
471 {NULL
} /* Sentinel */
474 PyTypeObject linetable_object_type
= {
475 PyVarObject_HEAD_INIT (NULL
, 0)
476 "gdb.LineTable", /*tp_name*/
477 sizeof (linetable_object
), /*tp_basicsize*/
479 ltpy_dealloc
, /*tp_dealloc*/
486 0, /*tp_as_sequence*/
494 Py_TPFLAGS_DEFAULT
, /*tp_flags*/
495 "GDB line table object", /* tp_doc */
498 0, /* tp_richcompare */
499 0, /* tp_weaklistoffset */
500 ltpy_iter
, /* tp_iter */
502 linetable_object_methods
, /* tp_methods */
507 0, /* tp_descr_get */
508 0, /* tp_descr_set */
509 0, /* tp_dictoffset */
514 static PyMethodDef ltpy_iterator_methods
[] = {
515 { "is_valid", ltpy_iter_is_valid
, METH_NOARGS
,
516 "is_valid () -> Boolean.\n\
517 Return True if this LineTable iterator is valid, False if not." },
518 {NULL
} /* Sentinel */
521 PyTypeObject ltpy_iterator_object_type
= {
522 PyVarObject_HEAD_INIT (NULL
, 0)
523 "gdb.LineTableIterator", /*tp_name*/
524 sizeof (ltpy_iterator_object
), /*tp_basicsize*/
526 ltpy_iterator_dealloc
, /*tp_dealloc*/
533 0, /*tp_as_sequence*/
541 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_ITER
, /*tp_flags*/
542 "GDB line table iterator object", /*tp_doc */
545 0, /*tp_richcompare */
546 0, /*tp_weaklistoffset */
547 ltpy_iterator
, /*tp_iter */
548 ltpy_iternext
, /*tp_iternext */
549 ltpy_iterator_methods
/*tp_methods */
553 static PyGetSetDef linetable_entry_object_getset
[] = {
554 { "line", ltpy_entry_get_line
, NULL
,
555 "The line number in the source file.", NULL
},
556 { "pc", ltpy_entry_get_pc
, NULL
,
557 "The memory address for this line number.", NULL
},
558 { NULL
} /* Sentinel */
561 PyTypeObject linetable_entry_object_type
= {
562 PyVarObject_HEAD_INIT (NULL
, 0)
563 "gdb.LineTableEntry", /*tp_name*/
564 sizeof (linetable_entry_object
), /*tp_basicsize*/
573 0, /*tp_as_sequence*/
581 Py_TPFLAGS_DEFAULT
, /*tp_flags*/
582 "GDB line table entry object", /* tp_doc */
585 0, /* tp_richcompare */
586 0, /* tp_weaklistoffset */
591 linetable_entry_object_getset
, /* tp_getset */
594 0, /* tp_descr_get */
595 0, /* tp_descr_set */
596 0, /* tp_dictoffset */