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"
25 /* The line table source line. */
27 /* The pc associated with the source line. */
29 } linetable_entry_object
;
31 extern PyTypeObject linetable_entry_object_type
32 CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("linetable_entry_object");
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
42 extern PyTypeObject linetable_object_type
43 CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("linetable_object");
47 /* The current entry in the line table for the iterator */
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. */
53 } ltpy_iterator_object
;
55 extern PyTypeObject ltpy_iterator_object_type
56 CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("ltpy_iterator_object");
58 /* Internal helper function to extract gdb.Symtab from a gdb.LineTable
62 get_symtab (PyObject
*linetable
)
64 linetable_object
*lt
= (linetable_object
*) linetable
;
69 #define LTPY_REQUIRE_VALID(lt_obj, symtab) \
71 symtab = symtab_object_to_symtab (get_symtab (lt_obj)); \
74 PyErr_SetString (PyExc_RuntimeError, \
75 _("Symbol Table in line table is invalid."));\
81 /* Helper function to create a line table object that wraps a
85 symtab_to_linetable_object (PyObject
*symtab
)
87 linetable_object
*ltable
;
89 ltable
= PyObject_New (linetable_object
, &linetable_object_type
);
92 ltable
->symtab
= symtab
;
95 return (PyObject
*) ltable
;
98 /* Internal helper function to build a line table object from a line
102 build_linetable_entry (int line
, CORE_ADDR address
)
104 linetable_entry_object
*obj
;
106 obj
= PyObject_New (linetable_entry_object
,
107 &linetable_entry_object_type
);
114 return (PyObject
*) obj
;
117 /* Internal helper function to build a Python Tuple from a GDB 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 VEC. Construct one line table entry object per
124 build_line_table_tuple_from_pcs (int line
, VEC (CORE_ADDR
) *vec
)
131 vec_len
= VEC_length (CORE_ADDR
, vec
);
135 tuple
= PyTuple_New (vec_len
);
140 for (i
= 0; VEC_iterate (CORE_ADDR
, vec
, i
, pc
); ++i
)
142 PyObject
*obj
= build_linetable_entry (line
, pc
);
150 else if (PyTuple_SetItem (tuple
, i
, obj
) != 0)
162 /* Implementation of gdb.LineTable.line (self) -> Tuple. Returns a
163 tuple of LineTableEntry objects associated with this line from the
164 in the line table. */
167 ltpy_get_pcs_for_line (PyObject
*self
, PyObject
*args
)
169 struct symtab
*symtab
;
170 gdb_py_longest py_line
;
171 struct linetable_entry
*best_entry
= NULL
;
172 VEC (CORE_ADDR
) *pcs
= NULL
;
175 LTPY_REQUIRE_VALID (self
, symtab
);
177 if (! PyArg_ParseTuple (args
, GDB_PY_LL_ARG
, &py_line
))
182 pcs
= find_pcs_for_symtab_line (symtab
, py_line
, &best_entry
);
184 CATCH (except
, RETURN_MASK_ALL
)
186 GDB_PY_HANDLE_EXCEPTION (except
);
190 tuple
= build_line_table_tuple_from_pcs (py_line
, pcs
);
191 VEC_free (CORE_ADDR
, pcs
);
196 /* Implementation of gdb.LineTable.has_line (self, line) -> Boolean.
197 Returns a Python Boolean indicating whether a source line has any
198 line table entries corresponding to it. */
201 ltpy_has_line (PyObject
*self
, PyObject
*args
)
203 struct symtab
*symtab
;
204 gdb_py_longest py_line
;
207 LTPY_REQUIRE_VALID (self
, symtab
);
209 if (! PyArg_ParseTuple (args
, GDB_PY_LL_ARG
, &py_line
))
212 if (SYMTAB_LINETABLE (symtab
) == NULL
)
214 PyErr_SetString (PyExc_RuntimeError
,
215 _("Linetable information not found in symbol table"));
219 for (index
= 0; index
< SYMTAB_LINETABLE (symtab
)->nitems
; index
++)
221 struct linetable_entry
*item
= &(SYMTAB_LINETABLE (symtab
)->item
[index
]);
222 if (item
->line
== py_line
)
229 /* Implementation of gdb.LineTable.source_lines (self) -> List.
230 Returns a Python List that contains source line entries in the
231 line table. This function will just return the source lines
232 without corresponding addresses. */
235 ltpy_get_all_source_lines (PyObject
*self
, PyObject
*args
)
237 struct symtab
*symtab
;
239 PyObject
*source_list
, *source_dict
, *line
;
240 struct linetable_entry
*item
;
242 LTPY_REQUIRE_VALID (self
, symtab
);
244 if (SYMTAB_LINETABLE (symtab
) == NULL
)
246 PyErr_SetString (PyExc_RuntimeError
,
247 _("Linetable information not found in symbol table"));
251 source_dict
= PyDict_New ();
252 if (source_dict
== NULL
)
255 for (index
= 0; index
< SYMTAB_LINETABLE (symtab
)->nitems
; index
++)
257 item
= &(SYMTAB_LINETABLE (symtab
)->item
[index
]);
259 /* 0 is used to signify end of line table information. Do not
260 include in the source set. */
263 line
= gdb_py_object_from_longest (item
->line
);
267 Py_DECREF (source_dict
);
271 if (PyDict_SetItem (source_dict
, line
, Py_None
) == -1)
274 Py_DECREF (source_dict
);
283 source_list
= PyDict_Keys (source_dict
);
284 Py_DECREF (source_dict
);
289 /* Implementation of gdb.LineTable.is_valid (self) -> Boolean.
290 Returns True if this line table object still exists in GDB. */
293 ltpy_is_valid (PyObject
*self
, PyObject
*args
)
295 struct symtab
*symtab
= NULL
;
297 symtab
= symtab_object_to_symtab (get_symtab (self
));
305 /* Deconstructor for the line table object. Decrement the reference
306 to the symbol table object before calling the default free. */
309 ltpy_dealloc (PyObject
*self
)
311 linetable_object
*obj
= (linetable_object
*) self
;
313 Py_DECREF (obj
->symtab
);
314 Py_TYPE (self
)->tp_free (self
);
317 /* Initialize LineTable, LineTableEntry and LineTableIterator
321 gdbpy_initialize_linetable (void)
323 if (PyType_Ready (&linetable_object_type
) < 0)
325 if (PyType_Ready (&linetable_entry_object_type
) < 0)
327 if (PyType_Ready (<py_iterator_object_type
) < 0)
330 Py_INCREF (&linetable_object_type
);
331 Py_INCREF (&linetable_entry_object_type
);
332 Py_INCREF (<py_iterator_object_type
);
334 if (gdb_pymodule_addobject (gdb_module
, "LineTable",
335 (PyObject
*) &linetable_object_type
) < 0)
338 if (gdb_pymodule_addobject (gdb_module
, "LineTableEntry",
339 (PyObject
*) &linetable_entry_object_type
) < 0)
342 if (gdb_pymodule_addobject (gdb_module
, "LineTableIterator",
343 (PyObject
*) <py_iterator_object_type
) < 0)
349 /* LineTable entry object get functions. */
351 /* Implementation of gdb.LineTableEntry.line (self) -> Long. Returns
352 a long integer associated with the line table entry. */
355 ltpy_entry_get_line (PyObject
*self
, void *closure
)
357 linetable_entry_object
*obj
= (linetable_entry_object
*) self
;
359 return gdb_py_object_from_longest (obj
->line
);
362 /* Implementation of gdb.LineTableEntry.pc (self) -> Long. Returns a
363 a long integer associated with the PC of the line table entry. */
366 ltpy_entry_get_pc (PyObject
*self
, void *closure
)
368 linetable_entry_object
*obj
= (linetable_entry_object
*) self
;
370 return gdb_py_object_from_longest (obj
->pc
);
373 /* LineTable iterator functions. */
375 /* Return a new line table iterator. */
378 ltpy_iter (PyObject
*self
)
380 ltpy_iterator_object
*ltpy_iter_obj
;
381 struct symtab
*symtab
= NULL
;
383 LTPY_REQUIRE_VALID (self
, symtab
);
385 ltpy_iter_obj
= PyObject_New (ltpy_iterator_object
,
386 <py_iterator_object_type
);
387 if (ltpy_iter_obj
== NULL
)
390 ltpy_iter_obj
->current_index
= 0;
391 ltpy_iter_obj
->source
= self
;
394 return (PyObject
*) ltpy_iter_obj
;
398 ltpy_iterator_dealloc (PyObject
*obj
)
400 ltpy_iterator_object
*iter_obj
= (ltpy_iterator_object
*) obj
;
402 Py_DECREF (iter_obj
->source
);
405 /* Return a reference to the line table iterator. */
408 ltpy_iterator (PyObject
*self
)
410 ltpy_iterator_object
*iter_obj
= (ltpy_iterator_object
*) self
;
411 struct symtab
*symtab
;
413 LTPY_REQUIRE_VALID (iter_obj
->source
, symtab
);
419 /* Return the next line table entry in the iteration through the line
420 table data structure. */
423 ltpy_iternext (PyObject
*self
)
425 ltpy_iterator_object
*iter_obj
= (ltpy_iterator_object
*) self
;
426 struct symtab
*symtab
;
428 struct linetable_entry
*item
;
430 LTPY_REQUIRE_VALID (iter_obj
->source
, symtab
);
432 if (iter_obj
->current_index
>= SYMTAB_LINETABLE (symtab
)->nitems
)
435 item
= &(SYMTAB_LINETABLE (symtab
)->item
[iter_obj
->current_index
]);
437 /* Skip over internal entries such as 0. 0 signifies the end of
438 line table data and is not useful to the API user. */
439 while (item
->line
< 1)
441 iter_obj
->current_index
++;
443 /* Exit if the internal value is the last item in the line table. */
444 if (iter_obj
->current_index
>= SYMTAB_LINETABLE (symtab
)->nitems
)
446 item
= &(SYMTAB_LINETABLE (symtab
)->item
[iter_obj
->current_index
]);
449 obj
= build_linetable_entry (item
->line
, item
->pc
);
450 iter_obj
->current_index
++;
455 PyErr_SetNone (PyExc_StopIteration
);
459 /* Implementation of gdb.LineTableIterator.is_valid (self) -> Boolean.
460 Returns True if this line table iterator object still exists in
464 ltpy_iter_is_valid (PyObject
*self
, PyObject
*args
)
466 struct symtab
*symtab
= NULL
;
467 ltpy_iterator_object
*iter_obj
= (ltpy_iterator_object
*) self
;
469 symtab
= symtab_object_to_symtab (get_symtab (iter_obj
->source
));
479 static PyMethodDef linetable_object_methods
[] = {
480 { "line", ltpy_get_pcs_for_line
, METH_VARARGS
,
481 "line (lineno) -> Tuple\n\
482 Return executable locations for a given source line." },
483 { "has_line", ltpy_has_line
, METH_VARARGS
,
484 "has_line (lineno) -> Boolean\n\
485 Return TRUE if this line has executable information, FALSE if not." },
486 { "source_lines", ltpy_get_all_source_lines
, METH_NOARGS
,
487 "source_lines () -> List\n\
488 Return a list of all executable source lines." },
489 { "is_valid", ltpy_is_valid
, METH_NOARGS
,
490 "is_valid () -> Boolean.\n\
491 Return True if this LineTable is valid, False if not." },
492 {NULL
} /* Sentinel */
495 PyTypeObject linetable_object_type
= {
496 PyVarObject_HEAD_INIT (NULL
, 0)
497 "gdb.LineTable", /*tp_name*/
498 sizeof (linetable_object
), /*tp_basicsize*/
500 ltpy_dealloc
, /*tp_dealloc*/
507 0, /*tp_as_sequence*/
515 Py_TPFLAGS_DEFAULT
, /*tp_flags*/
516 "GDB line table object", /* tp_doc */
519 0, /* tp_richcompare */
520 0, /* tp_weaklistoffset */
521 ltpy_iter
, /* tp_iter */
523 linetable_object_methods
, /* tp_methods */
528 0, /* tp_descr_get */
529 0, /* tp_descr_set */
530 0, /* tp_dictoffset */
535 static PyMethodDef ltpy_iterator_methods
[] = {
536 { "is_valid", ltpy_iter_is_valid
, METH_NOARGS
,
537 "is_valid () -> Boolean.\n\
538 Return True if this LineTable iterator is valid, False if not." },
539 {NULL
} /* Sentinel */
542 PyTypeObject ltpy_iterator_object_type
= {
543 PyVarObject_HEAD_INIT (NULL
, 0)
544 "gdb.LineTableIterator", /*tp_name*/
545 sizeof (ltpy_iterator_object
), /*tp_basicsize*/
547 ltpy_iterator_dealloc
, /*tp_dealloc*/
554 0, /*tp_as_sequence*/
562 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_ITER
, /*tp_flags*/
563 "GDB line table iterator object", /*tp_doc */
566 0, /*tp_richcompare */
567 0, /*tp_weaklistoffset */
568 ltpy_iterator
, /*tp_iter */
569 ltpy_iternext
, /*tp_iternext */
570 ltpy_iterator_methods
/*tp_methods */
574 static PyGetSetDef linetable_entry_object_getset
[] = {
575 { "line", ltpy_entry_get_line
, NULL
,
576 "The line number in the source file.", NULL
},
577 { "pc", ltpy_entry_get_pc
, NULL
,
578 "The memory address for this line number.", NULL
},
579 { NULL
} /* Sentinel */
582 PyTypeObject linetable_entry_object_type
= {
583 PyVarObject_HEAD_INIT (NULL
, 0)
584 "gdb.LineTableEntry", /*tp_name*/
585 sizeof (linetable_entry_object
), /*tp_basicsize*/
594 0, /*tp_as_sequence*/
602 Py_TPFLAGS_DEFAULT
, /*tp_flags*/
603 "GDB line table entry object", /* tp_doc */
606 0, /* tp_richcompare */
607 0, /* tp_weaklistoffset */
612 linetable_entry_object_getset
, /* tp_getset */
615 0, /* tp_descr_get */
616 0, /* tp_descr_set */
617 0, /* tp_dictoffset */