1 /* Python interface to line tables.
3 Copyright (C) 2013-2014 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"
22 #include "exceptions.h"
26 /* The line table source line. */
28 /* The pc associated with the source line. */
30 } linetable_entry_object
;
32 static 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 static 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 static 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
)
132 vec_len
= VEC_length (CORE_ADDR
, vec
);
136 tuple
= PyTuple_New (vec_len
);
141 for (i
= 0; VEC_iterate (CORE_ADDR
, vec
, i
, pc
); ++i
)
143 PyObject
*obj
= build_linetable_entry (line
, pc
);
151 else if (PyTuple_SetItem (tuple
, i
, obj
) != 0)
163 /* Implementation of gdb.LineTable.line (self) -> Tuple. Returns a
164 tuple of LineTableEntry objects associated with this line from the
165 in the line table. */
168 ltpy_get_pcs_for_line (PyObject
*self
, PyObject
*args
)
170 struct symtab
*symtab
;
172 struct linetable_entry
*best_entry
= NULL
;
173 linetable_entry_object
*result
;
174 VEC (CORE_ADDR
) *pcs
= NULL
;
176 volatile struct gdb_exception except
;
178 LTPY_REQUIRE_VALID (self
, symtab
);
180 if (! PyArg_ParseTuple (args
, GDB_PY_LL_ARG
, &py_line
))
183 TRY_CATCH (except
, RETURN_MASK_ALL
)
185 pcs
= find_pcs_for_symtab_line (symtab
, py_line
, &best_entry
);
187 GDB_PY_HANDLE_EXCEPTION (except
);
189 tuple
= build_line_table_tuple_from_pcs (py_line
, pcs
);
190 VEC_free (CORE_ADDR
, pcs
);
195 /* Implementation of gdb.LineTable.has_line (self, line) -> Boolean.
196 Returns a Python Boolean indicating whether a source line has any
197 line table entries corresponding to it. */
200 ltpy_has_line (PyObject
*self
, PyObject
*args
)
202 struct symtab
*symtab
;
206 LTPY_REQUIRE_VALID (self
, symtab
);
208 if (! PyArg_ParseTuple (args
, GDB_PY_LL_ARG
, &py_line
))
211 if (LINETABLE (symtab
) == NULL
)
213 PyErr_SetString (PyExc_RuntimeError
,
214 _("Linetable information not found in symbol table"));
218 for (index
= 0; index
< LINETABLE (symtab
)->nitems
; index
++)
220 struct linetable_entry
*item
= &(symtab
->linetable
->item
[index
]);
221 if (item
->line
== py_line
)
228 /* Implementation of gdb.LineTable.source_lines (self) -> FrozenSet.
229 Returns a Python FrozenSet that contains source line entries in the
230 line table. This function will just return the source lines
231 without corresponding addresses. */
234 ltpy_get_all_source_lines (PyObject
*self
, PyObject
*args
)
236 struct symtab
*symtab
;
238 PyObject
*source_list
, *source_dict
, *line
;
239 struct linetable_entry
*item
;
240 Py_ssize_t list_size
;
242 LTPY_REQUIRE_VALID (self
, symtab
);
244 if (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
< LINETABLE (symtab
)->nitems
; index
++)
257 item
= &(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
;
296 linetable_object
*obj
= (linetable_object
*) self
;
298 symtab
= symtab_object_to_symtab (get_symtab (self
));
306 /* Deconstructor for the line table object. Decrement the reference
307 to the symbol table object before calling the default free. */
310 ltpy_dealloc (PyObject
*self
)
312 linetable_object
*obj
= (linetable_object
*) self
;
314 Py_DECREF (obj
->symtab
);
315 Py_TYPE (self
)->tp_free (self
);
318 /* Initialize LineTable, LineTableEntry and LineTableIterator
322 gdbpy_initialize_linetable (void)
324 if (PyType_Ready (&linetable_object_type
) < 0)
326 if (PyType_Ready (&linetable_entry_object_type
) < 0)
328 if (PyType_Ready (<py_iterator_object_type
) < 0)
331 Py_INCREF (&linetable_object_type
);
332 Py_INCREF (&linetable_entry_object_type
);
333 Py_INCREF (<py_iterator_object_type
);
335 if (gdb_pymodule_addobject (gdb_module
, "LineTable",
336 (PyObject
*) &linetable_object_type
) < 0)
339 if (gdb_pymodule_addobject (gdb_module
, "LineTableEntry",
340 (PyObject
*) &linetable_entry_object_type
) < 0)
343 if (gdb_pymodule_addobject (gdb_module
, "LineTableIterator",
344 (PyObject
*) <py_iterator_object_type
) < 0)
350 /* Linetable entry object get functions. */
352 /* Implementation of gdb.LineTableEntry.line (self) -> Long. Returns
353 a long integer associated with the line table entry. */
356 ltpy_entry_get_line (PyObject
*self
, void *closure
)
358 linetable_entry_object
*obj
= (linetable_entry_object
*) self
;
360 return gdb_py_object_from_longest (obj
->line
);
363 /* Implementation of gdb.LineTableEntry.pc (self) -> Long. Returns a
364 a long integer associated with the PC of the line table entry. */
367 ltpy_entry_get_pc (PyObject
*self
, void *closure
)
369 linetable_entry_object
*obj
= (linetable_entry_object
*) self
;
371 return gdb_py_object_from_longest (obj
->pc
);
374 /* Linetable iterator functions. */
376 /* Return a new line table iterator. */
379 ltpy_iter (PyObject
*self
)
381 ltpy_iterator_object
*ltpy_iter_obj
;
382 struct symtab
*symtab
= NULL
;
384 LTPY_REQUIRE_VALID (self
, symtab
);
386 ltpy_iter_obj
= PyObject_New (ltpy_iterator_object
,
387 <py_iterator_object_type
);
388 if (ltpy_iter_obj
== NULL
)
391 ltpy_iter_obj
->current_index
= 0;
392 ltpy_iter_obj
->source
= self
;
395 return (PyObject
*) ltpy_iter_obj
;
399 ltpy_iterator_dealloc (PyObject
*obj
)
401 ltpy_iterator_object
*iter_obj
= (ltpy_iterator_object
*) obj
;
403 Py_DECREF (iter_obj
->source
);
406 /* Return a reference to the line table iterator. */
409 ltpy_iterator (PyObject
*self
)
411 ltpy_iterator_object
*iter_obj
= (ltpy_iterator_object
*) self
;
412 struct symtab
*symtab
;
414 LTPY_REQUIRE_VALID (iter_obj
->source
, symtab
);
420 /* Return the next line table entry in the iteration through the line
421 table data structure. */
424 ltpy_iternext (PyObject
*self
)
426 ltpy_iterator_object
*iter_obj
= (ltpy_iterator_object
*) self
;
427 struct symtab
*symtab
;
430 struct linetable_entry
*item
;
432 LTPY_REQUIRE_VALID (iter_obj
->source
, symtab
);
434 if (iter_obj
->current_index
>= LINETABLE (symtab
)->nitems
)
437 item
= &(LINETABLE (symtab
)->item
[iter_obj
->current_index
]);
439 /* Skip over internal entries such as 0. 0 signifies the end of
440 line table data and is not useful to the API user. */
441 while (item
->line
< 1)
443 iter_obj
->current_index
++;
445 /* Exit if the internal value is the last item in the line table. */
446 if (iter_obj
->current_index
>= symtab
->linetable
->nitems
)
448 item
= &(symtab
->linetable
->item
[iter_obj
->current_index
]);
451 obj
= build_linetable_entry (item
->line
, item
->pc
);
452 iter_obj
->current_index
++;
457 PyErr_SetNone (PyExc_StopIteration
);
461 /* Implementation of gdb.LinetableIterator.is_valid (self) -> Boolean.
462 Returns True if this line table iterator object still exists in
466 ltpy_iter_is_valid (PyObject
*self
, PyObject
*args
)
468 struct symtab
*symtab
= NULL
;
469 ltpy_iterator_object
*iter_obj
= (ltpy_iterator_object
*) self
;
471 symtab
= symtab_object_to_symtab (get_symtab (iter_obj
->source
));
481 static PyMethodDef linetable_object_methods
[] = {
482 { "line", ltpy_get_pcs_for_line
, METH_VARARGS
,
483 "line (lineno) -> Tuple\n\
484 Return executable locations for a given source line." },
485 { "has_line", ltpy_has_line
, METH_VARARGS
,
486 "has_line (lineno) -> Boolean\n\
487 Return TRUE if this line has executable information, FALSE if not." },
488 { "source_lines", ltpy_get_all_source_lines
, METH_NOARGS
,
489 "source_lines () -> FrozenSet\n\
490 Return a frozen set of all executable source lines." },
491 { "is_valid", ltpy_is_valid
, METH_NOARGS
,
492 "is_valid () -> Boolean.\n\
493 Return True if this Linetable is valid, False if not." },
494 {NULL
} /* Sentinel */
497 static PyTypeObject linetable_object_type
= {
498 PyVarObject_HEAD_INIT (NULL
, 0)
499 "gdb.LineTable", /*tp_name*/
500 sizeof (linetable_object
), /*tp_basicsize*/
502 ltpy_dealloc
, /*tp_dealloc*/
509 0, /*tp_as_sequence*/
517 Py_TPFLAGS_DEFAULT
, /*tp_flags*/
518 "GDB line table object", /* tp_doc */
521 0, /* tp_richcompare */
522 0, /* tp_weaklistoffset */
523 ltpy_iter
, /* tp_iter */
525 linetable_object_methods
, /* tp_methods */
530 0, /* tp_descr_get */
531 0, /* tp_descr_set */
532 0, /* tp_dictoffset */
537 static PyMethodDef ltpy_iterator_methods
[] = {
538 { "is_valid", ltpy_iter_is_valid
, METH_NOARGS
,
539 "is_valid () -> Boolean.\n\
540 Return True if this Linetable iterator is valid, False if not." },
541 {NULL
} /* Sentinel */
544 static PyTypeObject ltpy_iterator_object_type
= {
545 PyVarObject_HEAD_INIT (NULL
, 0)
546 "gdb.LineTableIterator", /*tp_name*/
547 sizeof (ltpy_iterator_object
), /*tp_basicsize*/
549 ltpy_iterator_dealloc
, /*tp_dealloc*/
556 0, /*tp_as_sequence*/
564 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_ITER
, /*tp_flags*/
565 "GDB line table iterator object", /*tp_doc */
568 0, /*tp_richcompare */
569 0, /*tp_weaklistoffset */
570 ltpy_iterator
, /*tp_iter */
571 ltpy_iternext
, /*tp_iternext */
572 ltpy_iterator_methods
/*tp_methods */
576 static PyGetSetDef linetable_entry_object_getset
[] = {
577 { "line", ltpy_entry_get_line
, NULL
,
578 "The line number in the source file.", NULL
},
579 { "pc", ltpy_entry_get_pc
, NULL
,
580 "The memory address for this line number.", NULL
},
581 { NULL
} /* Sentinel */
584 static PyTypeObject linetable_entry_object_type
= {
585 PyVarObject_HEAD_INIT (NULL
, 0)
586 "gdb.LineTableEntry", /*tp_name*/
587 sizeof (linetable_entry_object
), /*tp_basicsize*/
596 0, /*tp_as_sequence*/
604 Py_TPFLAGS_DEFAULT
, /*tp_flags*/
605 "GDB line table entry object", /* tp_doc */
608 0, /* tp_richcompare */
609 0, /* tp_weaklistoffset */
614 linetable_entry_object_getset
, /* tp_getset */
617 0, /* tp_descr_get */
618 0, /* tp_descr_set */
619 0, /* tp_dictoffset */