Fix new inferior events output
[deliverable/binutils-gdb.git] / gdb / python / py-linetable.c
CommitLineData
bc79de95
PM
1/* Python interface to line tables.
2
e2882c85 3 Copyright (C) 2013-2018 Free Software Foundation, Inc.
bc79de95
PM
4
5 This file is part of GDB.
6
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.
11
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.
16
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/>. */
19
20#include "defs.h"
21#include "python-internal.h"
87ce03fd 22#include "py-ref.h"
bc79de95
PM
23
24typedef struct {
25 PyObject_HEAD
26 /* The line table source line. */
27 int line;
28 /* The pc associated with the source line. */
29 CORE_ADDR pc;
30} linetable_entry_object;
31
e36122e9 32extern PyTypeObject linetable_entry_object_type
bc79de95
PM
33 CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("linetable_entry_object");
34
35typedef struct {
36 PyObject_HEAD
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
39 checks on it. */
40 PyObject *symtab;
41} linetable_object;
42
e36122e9 43extern PyTypeObject linetable_object_type
bc79de95
PM
44 CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("linetable_object");
45
46typedef struct {
47 PyObject_HEAD
48 /* The current entry in the line table for the iterator */
49 int current_index;
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. */
53 PyObject *source;
54} ltpy_iterator_object;
55
e36122e9 56extern PyTypeObject ltpy_iterator_object_type
bc79de95
PM
57 CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("ltpy_iterator_object");
58
4efd80aa 59/* Internal helper function to extract gdb.Symtab from a gdb.LineTable
bc79de95
PM
60 object. */
61
62static PyObject *
63get_symtab (PyObject *linetable)
64{
65 linetable_object *lt = (linetable_object *) linetable;
66
67 return lt->symtab;
68}
69
70#define LTPY_REQUIRE_VALID(lt_obj, symtab) \
71 do { \
72 symtab = symtab_object_to_symtab (get_symtab (lt_obj)); \
73 if (symtab == NULL) \
74 { \
75 PyErr_SetString (PyExc_RuntimeError, \
76 _("Symbol Table in line table is invalid."));\
77 return NULL; \
78 } \
79 } while (0)
80
81
82/* Helper function to create a line table object that wraps a
83 gdb.Symtab object. */
84
85PyObject *
86symtab_to_linetable_object (PyObject *symtab)
87{
88 linetable_object *ltable;
89
90 ltable = PyObject_New (linetable_object, &linetable_object_type);
91 if (ltable != NULL)
92 {
93 ltable->symtab = symtab;
94 Py_INCREF (symtab);
95 }
96 return (PyObject *) ltable;
97}
98
99/* Internal helper function to build a line table object from a line
100 and an address. */
101
102static PyObject *
103build_linetable_entry (int line, CORE_ADDR address)
104{
105 linetable_entry_object *obj;
106
107 obj = PyObject_New (linetable_entry_object,
108 &linetable_entry_object_type);
109 if (obj != NULL)
110 {
111 obj->line = line;
112 obj->pc = address;
113 }
114
115 return (PyObject *) obj;
116}
117
67d89901 118/* Internal helper function to build a Python Tuple from a vector.
bc79de95
PM
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
67d89901 121 from the line table PCS. Construct one line table entry object per
bc79de95
PM
122 address. */
123
124static PyObject *
67d89901 125build_line_table_tuple_from_pcs (int line, const std::vector<CORE_ADDR> &pcs)
bc79de95 126{
bc79de95
PM
127 int i;
128
67d89901 129 if (pcs.size () < 1)
bc79de95
PM
130 Py_RETURN_NONE;
131
67d89901 132 gdbpy_ref<> tuple (PyTuple_New (pcs.size ()));
bc79de95
PM
133
134 if (tuple == NULL)
135 return NULL;
136
67d89901 137 for (i = 0; i < pcs.size (); ++i)
bc79de95 138 {
67d89901 139 CORE_ADDR pc = pcs[i];
7780f186 140 gdbpy_ref<> obj (build_linetable_entry (line, pc));
bc79de95
PM
141
142 if (obj == NULL)
87ce03fd
TT
143 return NULL;
144 else if (PyTuple_SetItem (tuple.get (), i, obj.release ()) != 0)
145 return NULL;
bc79de95
PM
146 }
147
87ce03fd 148 return tuple.release ();
bc79de95
PM
149}
150
151/* Implementation of gdb.LineTable.line (self) -> Tuple. Returns a
152 tuple of LineTableEntry objects associated with this line from the
153 in the line table. */
154
155static PyObject *
156ltpy_get_pcs_for_line (PyObject *self, PyObject *args)
157{
158 struct symtab *symtab;
2a081c59 159 gdb_py_longest py_line;
bc79de95 160 struct linetable_entry *best_entry = NULL;
67d89901 161 std::vector<CORE_ADDR> pcs;
bc79de95
PM
162
163 LTPY_REQUIRE_VALID (self, symtab);
164
165 if (! PyArg_ParseTuple (args, GDB_PY_LL_ARG, &py_line))
166 return NULL;
167
492d29ea 168 TRY
bc79de95
PM
169 {
170 pcs = find_pcs_for_symtab_line (symtab, py_line, &best_entry);
171 }
492d29ea
PA
172 CATCH (except, RETURN_MASK_ALL)
173 {
174 GDB_PY_HANDLE_EXCEPTION (except);
175 }
176 END_CATCH
bc79de95 177
67d89901 178 return build_line_table_tuple_from_pcs (py_line, pcs);
bc79de95
PM
179}
180
181/* Implementation of gdb.LineTable.has_line (self, line) -> Boolean.
182 Returns a Python Boolean indicating whether a source line has any
183 line table entries corresponding to it. */
184
185static PyObject *
186ltpy_has_line (PyObject *self, PyObject *args)
187{
188 struct symtab *symtab;
2a081c59 189 gdb_py_longest py_line;
bc79de95
PM
190 int index;
191
192 LTPY_REQUIRE_VALID (self, symtab);
193
194 if (! PyArg_ParseTuple (args, GDB_PY_LL_ARG, &py_line))
195 return NULL;
196
8435453b 197 if (SYMTAB_LINETABLE (symtab) == NULL)
bc79de95
PM
198 {
199 PyErr_SetString (PyExc_RuntimeError,
200 _("Linetable information not found in symbol table"));
201 return NULL;
202 }
203
8435453b 204 for (index = 0; index < SYMTAB_LINETABLE (symtab)->nitems; index++)
bc79de95 205 {
8435453b 206 struct linetable_entry *item = &(SYMTAB_LINETABLE (symtab)->item[index]);
bc79de95
PM
207 if (item->line == py_line)
208 Py_RETURN_TRUE;
209 }
210
211 Py_RETURN_FALSE;
212}
213
7b849db4
CS
214/* Implementation of gdb.LineTable.source_lines (self) -> List.
215 Returns a Python List that contains source line entries in the
bc79de95
PM
216 line table. This function will just return the source lines
217 without corresponding addresses. */
218
219static PyObject *
220ltpy_get_all_source_lines (PyObject *self, PyObject *args)
221{
222 struct symtab *symtab;
223 Py_ssize_t index;
bc79de95 224 struct linetable_entry *item;
bc79de95
PM
225
226 LTPY_REQUIRE_VALID (self, symtab);
227
8435453b 228 if (SYMTAB_LINETABLE (symtab) == NULL)
bc79de95
PM
229 {
230 PyErr_SetString (PyExc_RuntimeError,
231 _("Linetable information not found in symbol table"));
232 return NULL;
233 }
234
7780f186 235 gdbpy_ref<> source_dict (PyDict_New ());
bc79de95
PM
236 if (source_dict == NULL)
237 return NULL;
238
8435453b 239 for (index = 0; index < SYMTAB_LINETABLE (symtab)->nitems; index++)
bc79de95 240 {
8435453b 241 item = &(SYMTAB_LINETABLE (symtab)->item[index]);
bc79de95
PM
242
243 /* 0 is used to signify end of line table information. Do not
244 include in the source set. */
245 if (item->line > 0)
246 {
7780f186 247 gdbpy_ref<> line (gdb_py_object_from_longest (item->line));
bc79de95
PM
248
249 if (line == NULL)
87ce03fd
TT
250 return NULL;
251
252 if (PyDict_SetItem (source_dict.get (), line.get (), Py_None) == -1)
253 return NULL;
bc79de95
PM
254 }
255 }
256
87ce03fd 257 return PyDict_Keys (source_dict.get ());
bc79de95
PM
258}
259
4efd80aa 260/* Implementation of gdb.LineTable.is_valid (self) -> Boolean.
bc79de95
PM
261 Returns True if this line table object still exists in GDB. */
262
263static PyObject *
264ltpy_is_valid (PyObject *self, PyObject *args)
265{
266 struct symtab *symtab = NULL;
bc79de95
PM
267
268 symtab = symtab_object_to_symtab (get_symtab (self));
269
270 if (symtab == NULL)
271 Py_RETURN_FALSE;
272
273 Py_RETURN_TRUE;
274}
275
276/* Deconstructor for the line table object. Decrement the reference
277 to the symbol table object before calling the default free. */
278
279static void
280ltpy_dealloc (PyObject *self)
281{
282 linetable_object *obj = (linetable_object *) self;
283
284 Py_DECREF (obj->symtab);
285 Py_TYPE (self)->tp_free (self);
286}
287
288/* Initialize LineTable, LineTableEntry and LineTableIterator
289 objects. */
290
291int
292gdbpy_initialize_linetable (void)
293{
294 if (PyType_Ready (&linetable_object_type) < 0)
295 return -1;
296 if (PyType_Ready (&linetable_entry_object_type) < 0)
297 return -1;
298 if (PyType_Ready (&ltpy_iterator_object_type) < 0)
299 return -1;
300
301 Py_INCREF (&linetable_object_type);
302 Py_INCREF (&linetable_entry_object_type);
303 Py_INCREF (&ltpy_iterator_object_type);
304
305 if (gdb_pymodule_addobject (gdb_module, "LineTable",
306 (PyObject *) &linetable_object_type) < 0)
307 return -1;
308
309 if (gdb_pymodule_addobject (gdb_module, "LineTableEntry",
310 (PyObject *) &linetable_entry_object_type) < 0)
311 return -1;
312
313 if (gdb_pymodule_addobject (gdb_module, "LineTableIterator",
314 (PyObject *) &ltpy_iterator_object_type) < 0)
315 return -1;
316
317 return 0;
318}
319
4efd80aa 320/* LineTable entry object get functions. */
bc79de95
PM
321
322/* Implementation of gdb.LineTableEntry.line (self) -> Long. Returns
323 a long integer associated with the line table entry. */
324
325static PyObject *
326ltpy_entry_get_line (PyObject *self, void *closure)
327{
328 linetable_entry_object *obj = (linetable_entry_object *) self;
329
330 return gdb_py_object_from_longest (obj->line);
331}
332
333/* Implementation of gdb.LineTableEntry.pc (self) -> Long. Returns a
334 a long integer associated with the PC of the line table entry. */
335
336static PyObject *
337ltpy_entry_get_pc (PyObject *self, void *closure)
338{
339 linetable_entry_object *obj = (linetable_entry_object *) self;
340
341 return gdb_py_object_from_longest (obj->pc);
342}
343
4efd80aa 344/* LineTable iterator functions. */
bc79de95
PM
345
346/* Return a new line table iterator. */
347
348static PyObject *
349ltpy_iter (PyObject *self)
350{
351 ltpy_iterator_object *ltpy_iter_obj;
352 struct symtab *symtab = NULL;
353
354 LTPY_REQUIRE_VALID (self, symtab);
355
356 ltpy_iter_obj = PyObject_New (ltpy_iterator_object,
357 &ltpy_iterator_object_type);
358 if (ltpy_iter_obj == NULL)
359 return NULL;
360
361 ltpy_iter_obj->current_index = 0;
362 ltpy_iter_obj->source = self;
363
364 Py_INCREF (self);
365 return (PyObject *) ltpy_iter_obj;
366}
367
368static void
369ltpy_iterator_dealloc (PyObject *obj)
370{
371 ltpy_iterator_object *iter_obj = (ltpy_iterator_object *) obj;
372
373 Py_DECREF (iter_obj->source);
374}
375
376/* Return a reference to the line table iterator. */
377
378static PyObject *
379ltpy_iterator (PyObject *self)
380{
381 ltpy_iterator_object *iter_obj = (ltpy_iterator_object *) self;
382 struct symtab *symtab;
383
384 LTPY_REQUIRE_VALID (iter_obj->source, symtab);
385
386 Py_INCREF (self);
387 return self;
388}
389
390/* Return the next line table entry in the iteration through the line
391 table data structure. */
392
393static PyObject *
394ltpy_iternext (PyObject *self)
395{
396 ltpy_iterator_object *iter_obj = (ltpy_iterator_object *) self;
397 struct symtab *symtab;
bc79de95
PM
398 PyObject *obj;
399 struct linetable_entry *item;
400
401 LTPY_REQUIRE_VALID (iter_obj->source, symtab);
402
8435453b 403 if (iter_obj->current_index >= SYMTAB_LINETABLE (symtab)->nitems)
2bb8f231
TT
404 {
405 PyErr_SetNone (PyExc_StopIteration);
406 return NULL;
407 }
bc79de95 408
8435453b 409 item = &(SYMTAB_LINETABLE (symtab)->item[iter_obj->current_index]);
bc79de95
PM
410
411 /* Skip over internal entries such as 0. 0 signifies the end of
412 line table data and is not useful to the API user. */
413 while (item->line < 1)
414 {
415 iter_obj->current_index++;
416
417 /* Exit if the internal value is the last item in the line table. */
8435453b 418 if (iter_obj->current_index >= SYMTAB_LINETABLE (symtab)->nitems)
2bb8f231
TT
419 {
420 PyErr_SetNone (PyExc_StopIteration);
421 return NULL;
422 }
8435453b 423 item = &(SYMTAB_LINETABLE (symtab)->item[iter_obj->current_index]);
bc79de95
PM
424 }
425
426 obj = build_linetable_entry (item->line, item->pc);
427 iter_obj->current_index++;
428
429 return obj;
bc79de95
PM
430}
431
4efd80aa 432/* Implementation of gdb.LineTableIterator.is_valid (self) -> Boolean.
bc79de95
PM
433 Returns True if this line table iterator object still exists in
434 GDB. */
435
436static PyObject *
437ltpy_iter_is_valid (PyObject *self, PyObject *args)
438{
439 struct symtab *symtab = NULL;
440 ltpy_iterator_object *iter_obj = (ltpy_iterator_object *) self;
441
442 symtab = symtab_object_to_symtab (get_symtab (iter_obj->source));
443
444 if (symtab == NULL)
445 Py_RETURN_FALSE;
446
447 Py_RETURN_TRUE;
448}
449
450\f
451
452static PyMethodDef linetable_object_methods[] = {
453 { "line", ltpy_get_pcs_for_line, METH_VARARGS,
454 "line (lineno) -> Tuple\n\
455Return executable locations for a given source line." },
456 { "has_line", ltpy_has_line, METH_VARARGS,
457 "has_line (lineno) -> Boolean\n\
458Return TRUE if this line has executable information, FALSE if not." },
459 { "source_lines", ltpy_get_all_source_lines, METH_NOARGS,
7b849db4
CS
460 "source_lines () -> List\n\
461Return a list of all executable source lines." },
bc79de95
PM
462 { "is_valid", ltpy_is_valid, METH_NOARGS,
463 "is_valid () -> Boolean.\n\
4efd80aa 464Return True if this LineTable is valid, False if not." },
bc79de95
PM
465 {NULL} /* Sentinel */
466};
467
e36122e9 468PyTypeObject linetable_object_type = {
bc79de95
PM
469 PyVarObject_HEAD_INIT (NULL, 0)
470 "gdb.LineTable", /*tp_name*/
471 sizeof (linetable_object), /*tp_basicsize*/
472 0, /*tp_itemsize*/
473 ltpy_dealloc, /*tp_dealloc*/
474 0, /*tp_print*/
475 0, /*tp_getattr*/
476 0, /*tp_setattr*/
477 0, /*tp_compare*/
478 0, /*tp_repr*/
479 0, /*tp_as_number*/
480 0, /*tp_as_sequence*/
481 0, /*tp_as_mapping*/
482 0, /*tp_hash */
483 0, /*tp_call*/
484 0, /*tp_str*/
485 0, /*tp_getattro*/
486 0, /*tp_setattro*/
487 0, /*tp_as_buffer*/
488 Py_TPFLAGS_DEFAULT, /*tp_flags*/
489 "GDB line table object", /* tp_doc */
490 0, /* tp_traverse */
491 0, /* tp_clear */
492 0, /* tp_richcompare */
493 0, /* tp_weaklistoffset */
494 ltpy_iter, /* tp_iter */
495 0, /* tp_iternext */
496 linetable_object_methods, /* tp_methods */
497 0, /* tp_members */
498 0, /* tp_getset */
499 0, /* tp_base */
500 0, /* tp_dict */
501 0, /* tp_descr_get */
502 0, /* tp_descr_set */
503 0, /* tp_dictoffset */
504 0, /* tp_init */
505 0, /* tp_alloc */
506};
507
508static PyMethodDef ltpy_iterator_methods[] = {
509 { "is_valid", ltpy_iter_is_valid, METH_NOARGS,
510 "is_valid () -> Boolean.\n\
4efd80aa 511Return True if this LineTable iterator is valid, False if not." },
bc79de95
PM
512 {NULL} /* Sentinel */
513};
514
e36122e9 515PyTypeObject ltpy_iterator_object_type = {
bc79de95
PM
516 PyVarObject_HEAD_INIT (NULL, 0)
517 "gdb.LineTableIterator", /*tp_name*/
518 sizeof (ltpy_iterator_object), /*tp_basicsize*/
519 0, /*tp_itemsize*/
520 ltpy_iterator_dealloc, /*tp_dealloc*/
521 0, /*tp_print*/
522 0, /*tp_getattr*/
523 0, /*tp_setattr*/
524 0, /*tp_compare*/
525 0, /*tp_repr*/
526 0, /*tp_as_number*/
527 0, /*tp_as_sequence*/
528 0, /*tp_as_mapping*/
529 0, /*tp_hash */
530 0, /*tp_call*/
531 0, /*tp_str*/
532 0, /*tp_getattro*/
533 0, /*tp_setattro*/
534 0, /*tp_as_buffer*/
535 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_ITER, /*tp_flags*/
536 "GDB line table iterator object", /*tp_doc */
537 0, /*tp_traverse */
538 0, /*tp_clear */
539 0, /*tp_richcompare */
540 0, /*tp_weaklistoffset */
541 ltpy_iterator, /*tp_iter */
542 ltpy_iternext, /*tp_iternext */
543 ltpy_iterator_methods /*tp_methods */
544};
545
546
0d1f4ceb 547static gdb_PyGetSetDef linetable_entry_object_getset[] = {
bc79de95
PM
548 { "line", ltpy_entry_get_line, NULL,
549 "The line number in the source file.", NULL },
550 { "pc", ltpy_entry_get_pc, NULL,
551 "The memory address for this line number.", NULL },
552 { NULL } /* Sentinel */
553};
554
e36122e9 555PyTypeObject linetable_entry_object_type = {
bc79de95
PM
556 PyVarObject_HEAD_INIT (NULL, 0)
557 "gdb.LineTableEntry", /*tp_name*/
558 sizeof (linetable_entry_object), /*tp_basicsize*/
559 0, /*tp_itemsize*/
560 0, /*tp_dealloc*/
561 0, /*tp_print*/
562 0, /*tp_getattr*/
563 0, /*tp_setattr*/
564 0, /*tp_compare*/
565 0, /*tp_repr*/
566 0, /*tp_as_number*/
567 0, /*tp_as_sequence*/
568 0, /*tp_as_mapping*/
569 0, /*tp_hash */
570 0, /*tp_call*/
571 0, /*tp_str*/
572 0, /*tp_getattro*/
573 0, /*tp_setattro*/
574 0, /*tp_as_buffer*/
575 Py_TPFLAGS_DEFAULT, /*tp_flags*/
576 "GDB line table entry object", /* tp_doc */
577 0, /* tp_traverse */
578 0, /* tp_clear */
579 0, /* tp_richcompare */
580 0, /* tp_weaklistoffset */
581 0, /* tp_iter */
582 0, /* tp_iternext */
583 0, /* tp_methods */
584 0, /* tp_members */
585 linetable_entry_object_getset, /* tp_getset */
586 0, /* tp_base */
587 0, /* tp_dict */
588 0, /* tp_descr_get */
589 0, /* tp_descr_set */
590 0, /* tp_dictoffset */
591 0, /* tp_init */
592 0, /* tp_alloc */
593};
This page took 0.448822 seconds and 4 git commands to generate.