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
)
412 item
= &(SYMTAB_LINETABLE (symtab
)->item
[iter_obj
->current_index
]);
414 /* Skip over internal entries such as 0. 0 signifies the end of
415 line table data and is not useful to the API user. */
416 while (item
->line
< 1)
418 iter_obj
->current_index
++;
420 /* Exit if the internal value is the last item in the line table. */
421 if (iter_obj
->current_index
>= SYMTAB_LINETABLE (symtab
)->nitems
)
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 PyErr_SetNone (PyExc_StopIteration
);
436 /* Implementation of gdb.LineTableIterator.is_valid (self) -> Boolean.
437 Returns True if this line table iterator object still exists in
441 ltpy_iter_is_valid (PyObject
*self
, PyObject
*args
)
443 struct symtab
*symtab
= NULL
;
444 ltpy_iterator_object
*iter_obj
= (ltpy_iterator_object
*) self
;
446 symtab
= symtab_object_to_symtab (get_symtab (iter_obj
->source
));
456 static PyMethodDef linetable_object_methods
[] = {
457 { "line", ltpy_get_pcs_for_line
, METH_VARARGS
,
458 "line (lineno) -> Tuple\n\
459 Return executable locations for a given source line." },
460 { "has_line", ltpy_has_line
, METH_VARARGS
,
461 "has_line (lineno) -> Boolean\n\
462 Return TRUE if this line has executable information, FALSE if not." },
463 { "source_lines", ltpy_get_all_source_lines
, METH_NOARGS
,
464 "source_lines () -> List\n\
465 Return a list of all executable source lines." },
466 { "is_valid", ltpy_is_valid
, METH_NOARGS
,
467 "is_valid () -> Boolean.\n\
468 Return True if this LineTable is valid, False if not." },
469 {NULL
} /* Sentinel */
472 PyTypeObject linetable_object_type
= {
473 PyVarObject_HEAD_INIT (NULL
, 0)
474 "gdb.LineTable", /*tp_name*/
475 sizeof (linetable_object
), /*tp_basicsize*/
477 ltpy_dealloc
, /*tp_dealloc*/
484 0, /*tp_as_sequence*/
492 Py_TPFLAGS_DEFAULT
, /*tp_flags*/
493 "GDB line table object", /* tp_doc */
496 0, /* tp_richcompare */
497 0, /* tp_weaklistoffset */
498 ltpy_iter
, /* tp_iter */
500 linetable_object_methods
, /* tp_methods */
505 0, /* tp_descr_get */
506 0, /* tp_descr_set */
507 0, /* tp_dictoffset */
512 static PyMethodDef ltpy_iterator_methods
[] = {
513 { "is_valid", ltpy_iter_is_valid
, METH_NOARGS
,
514 "is_valid () -> Boolean.\n\
515 Return True if this LineTable iterator is valid, False if not." },
516 {NULL
} /* Sentinel */
519 PyTypeObject ltpy_iterator_object_type
= {
520 PyVarObject_HEAD_INIT (NULL
, 0)
521 "gdb.LineTableIterator", /*tp_name*/
522 sizeof (ltpy_iterator_object
), /*tp_basicsize*/
524 ltpy_iterator_dealloc
, /*tp_dealloc*/
531 0, /*tp_as_sequence*/
539 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_ITER
, /*tp_flags*/
540 "GDB line table iterator object", /*tp_doc */
543 0, /*tp_richcompare */
544 0, /*tp_weaklistoffset */
545 ltpy_iterator
, /*tp_iter */
546 ltpy_iternext
, /*tp_iternext */
547 ltpy_iterator_methods
/*tp_methods */
551 static PyGetSetDef linetable_entry_object_getset
[] = {
552 { "line", ltpy_entry_get_line
, NULL
,
553 "The line number in the source file.", NULL
},
554 { "pc", ltpy_entry_get_pc
, NULL
,
555 "The memory address for this line number.", NULL
},
556 { NULL
} /* Sentinel */
559 PyTypeObject linetable_entry_object_type
= {
560 PyVarObject_HEAD_INIT (NULL
, 0)
561 "gdb.LineTableEntry", /*tp_name*/
562 sizeof (linetable_entry_object
), /*tp_basicsize*/
571 0, /*tp_as_sequence*/
579 Py_TPFLAGS_DEFAULT
, /*tp_flags*/
580 "GDB line table entry object", /* tp_doc */
583 0, /* tp_richcompare */
584 0, /* tp_weaklistoffset */
589 linetable_entry_object_getset
, /* tp_getset */
592 0, /* tp_descr_get */
593 0, /* tp_descr_set */
594 0, /* tp_dictoffset */