1 /* Python interface to line tables.
3 Copyright (C) 2013-2015 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 linetable_entry_object
*result
;
173 VEC (CORE_ADDR
) *pcs
= NULL
;
176 LTPY_REQUIRE_VALID (self
, symtab
);
178 if (! PyArg_ParseTuple (args
, GDB_PY_LL_ARG
, &py_line
))
183 pcs
= find_pcs_for_symtab_line (symtab
, py_line
, &best_entry
);
185 CATCH (except
, RETURN_MASK_ALL
)
187 GDB_PY_HANDLE_EXCEPTION (except
);
191 tuple
= build_line_table_tuple_from_pcs (py_line
, pcs
);
192 VEC_free (CORE_ADDR
, pcs
);
197 /* Implementation of gdb.LineTable.has_line (self, line) -> Boolean.
198 Returns a Python Boolean indicating whether a source line has any
199 line table entries corresponding to it. */
202 ltpy_has_line (PyObject
*self
, PyObject
*args
)
204 struct symtab
*symtab
;
205 gdb_py_longest py_line
;
208 LTPY_REQUIRE_VALID (self
, symtab
);
210 if (! PyArg_ParseTuple (args
, GDB_PY_LL_ARG
, &py_line
))
213 if (SYMTAB_LINETABLE (symtab
) == NULL
)
215 PyErr_SetString (PyExc_RuntimeError
,
216 _("Linetable information not found in symbol table"));
220 for (index
= 0; index
< SYMTAB_LINETABLE (symtab
)->nitems
; index
++)
222 struct linetable_entry
*item
= &(SYMTAB_LINETABLE (symtab
)->item
[index
]);
223 if (item
->line
== py_line
)
230 /* Implementation of gdb.LineTable.source_lines (self) -> List.
231 Returns a Python List that contains source line entries in the
232 line table. This function will just return the source lines
233 without corresponding addresses. */
236 ltpy_get_all_source_lines (PyObject
*self
, PyObject
*args
)
238 struct symtab
*symtab
;
240 PyObject
*source_list
, *source_dict
, *line
;
241 struct linetable_entry
*item
;
242 Py_ssize_t list_size
;
244 LTPY_REQUIRE_VALID (self
, symtab
);
246 if (SYMTAB_LINETABLE (symtab
) == NULL
)
248 PyErr_SetString (PyExc_RuntimeError
,
249 _("Linetable information not found in symbol table"));
253 source_dict
= PyDict_New ();
254 if (source_dict
== NULL
)
257 for (index
= 0; index
< SYMTAB_LINETABLE (symtab
)->nitems
; index
++)
259 item
= &(SYMTAB_LINETABLE (symtab
)->item
[index
]);
261 /* 0 is used to signify end of line table information. Do not
262 include in the source set. */
265 line
= gdb_py_object_from_longest (item
->line
);
269 Py_DECREF (source_dict
);
273 if (PyDict_SetItem (source_dict
, line
, Py_None
) == -1)
276 Py_DECREF (source_dict
);
285 source_list
= PyDict_Keys (source_dict
);
286 Py_DECREF (source_dict
);
291 /* Implementation of gdb.LineTable.is_valid (self) -> Boolean.
292 Returns True if this line table object still exists in GDB. */
295 ltpy_is_valid (PyObject
*self
, PyObject
*args
)
297 struct symtab
*symtab
= NULL
;
298 linetable_object
*obj
= (linetable_object
*) self
;
300 symtab
= symtab_object_to_symtab (get_symtab (self
));
308 /* Deconstructor for the line table object. Decrement the reference
309 to the symbol table object before calling the default free. */
312 ltpy_dealloc (PyObject
*self
)
314 linetable_object
*obj
= (linetable_object
*) self
;
316 Py_DECREF (obj
->symtab
);
317 Py_TYPE (self
)->tp_free (self
);
320 /* Initialize LineTable, LineTableEntry and LineTableIterator
324 gdbpy_initialize_linetable (void)
326 if (PyType_Ready (&linetable_object_type
) < 0)
328 if (PyType_Ready (&linetable_entry_object_type
) < 0)
330 if (PyType_Ready (<py_iterator_object_type
) < 0)
333 Py_INCREF (&linetable_object_type
);
334 Py_INCREF (&linetable_entry_object_type
);
335 Py_INCREF (<py_iterator_object_type
);
337 if (gdb_pymodule_addobject (gdb_module
, "LineTable",
338 (PyObject
*) &linetable_object_type
) < 0)
341 if (gdb_pymodule_addobject (gdb_module
, "LineTableEntry",
342 (PyObject
*) &linetable_entry_object_type
) < 0)
345 if (gdb_pymodule_addobject (gdb_module
, "LineTableIterator",
346 (PyObject
*) <py_iterator_object_type
) < 0)
352 /* LineTable entry object get functions. */
354 /* Implementation of gdb.LineTableEntry.line (self) -> Long. Returns
355 a long integer associated with the line table entry. */
358 ltpy_entry_get_line (PyObject
*self
, void *closure
)
360 linetable_entry_object
*obj
= (linetable_entry_object
*) self
;
362 return gdb_py_object_from_longest (obj
->line
);
365 /* Implementation of gdb.LineTableEntry.pc (self) -> Long. Returns a
366 a long integer associated with the PC of the line table entry. */
369 ltpy_entry_get_pc (PyObject
*self
, void *closure
)
371 linetable_entry_object
*obj
= (linetable_entry_object
*) self
;
373 return gdb_py_object_from_longest (obj
->pc
);
376 /* LineTable iterator functions. */
378 /* Return a new line table iterator. */
381 ltpy_iter (PyObject
*self
)
383 ltpy_iterator_object
*ltpy_iter_obj
;
384 struct symtab
*symtab
= NULL
;
386 LTPY_REQUIRE_VALID (self
, symtab
);
388 ltpy_iter_obj
= PyObject_New (ltpy_iterator_object
,
389 <py_iterator_object_type
);
390 if (ltpy_iter_obj
== NULL
)
393 ltpy_iter_obj
->current_index
= 0;
394 ltpy_iter_obj
->source
= self
;
397 return (PyObject
*) ltpy_iter_obj
;
401 ltpy_iterator_dealloc (PyObject
*obj
)
403 ltpy_iterator_object
*iter_obj
= (ltpy_iterator_object
*) obj
;
405 Py_DECREF (iter_obj
->source
);
408 /* Return a reference to the line table iterator. */
411 ltpy_iterator (PyObject
*self
)
413 ltpy_iterator_object
*iter_obj
= (ltpy_iterator_object
*) self
;
414 struct symtab
*symtab
;
416 LTPY_REQUIRE_VALID (iter_obj
->source
, symtab
);
422 /* Return the next line table entry in the iteration through the line
423 table data structure. */
426 ltpy_iternext (PyObject
*self
)
428 ltpy_iterator_object
*iter_obj
= (ltpy_iterator_object
*) self
;
429 struct symtab
*symtab
;
432 struct linetable_entry
*item
;
434 LTPY_REQUIRE_VALID (iter_obj
->source
, symtab
);
436 if (iter_obj
->current_index
>= SYMTAB_LINETABLE (symtab
)->nitems
)
439 item
= &(SYMTAB_LINETABLE (symtab
)->item
[iter_obj
->current_index
]);
441 /* Skip over internal entries such as 0. 0 signifies the end of
442 line table data and is not useful to the API user. */
443 while (item
->line
< 1)
445 iter_obj
->current_index
++;
447 /* Exit if the internal value is the last item in the line table. */
448 if (iter_obj
->current_index
>= SYMTAB_LINETABLE (symtab
)->nitems
)
450 item
= &(SYMTAB_LINETABLE (symtab
)->item
[iter_obj
->current_index
]);
453 obj
= build_linetable_entry (item
->line
, item
->pc
);
454 iter_obj
->current_index
++;
459 PyErr_SetNone (PyExc_StopIteration
);
463 /* Implementation of gdb.LineTableIterator.is_valid (self) -> Boolean.
464 Returns True if this line table iterator object still exists in
468 ltpy_iter_is_valid (PyObject
*self
, PyObject
*args
)
470 struct symtab
*symtab
= NULL
;
471 ltpy_iterator_object
*iter_obj
= (ltpy_iterator_object
*) self
;
473 symtab
= symtab_object_to_symtab (get_symtab (iter_obj
->source
));
483 static PyMethodDef linetable_object_methods
[] = {
484 { "line", ltpy_get_pcs_for_line
, METH_VARARGS
,
485 "line (lineno) -> Tuple\n\
486 Return executable locations for a given source line." },
487 { "has_line", ltpy_has_line
, METH_VARARGS
,
488 "has_line (lineno) -> Boolean\n\
489 Return TRUE if this line has executable information, FALSE if not." },
490 { "source_lines", ltpy_get_all_source_lines
, METH_NOARGS
,
491 "source_lines () -> List\n\
492 Return a list of all executable source lines." },
493 { "is_valid", ltpy_is_valid
, METH_NOARGS
,
494 "is_valid () -> Boolean.\n\
495 Return True if this LineTable is valid, False if not." },
496 {NULL
} /* Sentinel */
499 PyTypeObject linetable_object_type
= {
500 PyVarObject_HEAD_INIT (NULL
, 0)
501 "gdb.LineTable", /*tp_name*/
502 sizeof (linetable_object
), /*tp_basicsize*/
504 ltpy_dealloc
, /*tp_dealloc*/
511 0, /*tp_as_sequence*/
519 Py_TPFLAGS_DEFAULT
, /*tp_flags*/
520 "GDB line table object", /* tp_doc */
523 0, /* tp_richcompare */
524 0, /* tp_weaklistoffset */
525 ltpy_iter
, /* tp_iter */
527 linetable_object_methods
, /* tp_methods */
532 0, /* tp_descr_get */
533 0, /* tp_descr_set */
534 0, /* tp_dictoffset */
539 static PyMethodDef ltpy_iterator_methods
[] = {
540 { "is_valid", ltpy_iter_is_valid
, METH_NOARGS
,
541 "is_valid () -> Boolean.\n\
542 Return True if this LineTable iterator is valid, False if not." },
543 {NULL
} /* Sentinel */
546 PyTypeObject ltpy_iterator_object_type
= {
547 PyVarObject_HEAD_INIT (NULL
, 0)
548 "gdb.LineTableIterator", /*tp_name*/
549 sizeof (ltpy_iterator_object
), /*tp_basicsize*/
551 ltpy_iterator_dealloc
, /*tp_dealloc*/
558 0, /*tp_as_sequence*/
566 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_ITER
, /*tp_flags*/
567 "GDB line table iterator object", /*tp_doc */
570 0, /*tp_richcompare */
571 0, /*tp_weaklistoffset */
572 ltpy_iterator
, /*tp_iter */
573 ltpy_iternext
, /*tp_iternext */
574 ltpy_iterator_methods
/*tp_methods */
578 static PyGetSetDef linetable_entry_object_getset
[] = {
579 { "line", ltpy_entry_get_line
, NULL
,
580 "The line number in the source file.", NULL
},
581 { "pc", ltpy_entry_get_pc
, NULL
,
582 "The memory address for this line number.", NULL
},
583 { NULL
} /* Sentinel */
586 PyTypeObject linetable_entry_object_type
= {
587 PyVarObject_HEAD_INIT (NULL
, 0)
588 "gdb.LineTableEntry", /*tp_name*/
589 sizeof (linetable_entry_object
), /*tp_basicsize*/
598 0, /*tp_as_sequence*/
606 Py_TPFLAGS_DEFAULT
, /*tp_flags*/
607 "GDB line table entry object", /* tp_doc */
610 0, /* tp_richcompare */
611 0, /* tp_weaklistoffset */
616 linetable_entry_object_getset
, /* tp_getset */
619 0, /* tp_descr_get */
620 0, /* tp_descr_set */
621 0, /* tp_dictoffset */