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