Add FreeBSD/mips architecture.
[deliverable/binutils-gdb.git] / gdb / python / py-linetable.c
CommitLineData
bc79de95
PM
1/* Python interface to line tables.
2
61baf725 3 Copyright (C) 2013-2017 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
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
121 address. */
122
123static PyObject *
124build_line_table_tuple_from_pcs (int line, VEC (CORE_ADDR) *vec)
125{
126 int vec_len = 0;
127 PyObject *tuple;
128 CORE_ADDR pc;
129 int i;
130
131 vec_len = VEC_length (CORE_ADDR, vec);
132 if (vec_len < 1)
133 Py_RETURN_NONE;
134
135 tuple = PyTuple_New (vec_len);
136
137 if (tuple == NULL)
138 return NULL;
139
140 for (i = 0; VEC_iterate (CORE_ADDR, vec, i, pc); ++i)
141 {
142 PyObject *obj = build_linetable_entry (line, pc);
143
144 if (obj == NULL)
145 {
146 Py_DECREF (tuple);
147 tuple = NULL;
148 break;
149 }
150 else if (PyTuple_SetItem (tuple, i, obj) != 0)
151 {
152 Py_DECREF (obj);
153 Py_DECREF (tuple);
154 tuple = NULL;
155 break;
156 }
157 }
158
159 return tuple;
160}
161
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. */
165
166static PyObject *
167ltpy_get_pcs_for_line (PyObject *self, PyObject *args)
168{
169 struct symtab *symtab;
2a081c59 170 gdb_py_longest py_line;
bc79de95 171 struct linetable_entry *best_entry = NULL;
bc79de95
PM
172 VEC (CORE_ADDR) *pcs = NULL;
173 PyObject *tuple;
bc79de95
PM
174
175 LTPY_REQUIRE_VALID (self, symtab);
176
177 if (! PyArg_ParseTuple (args, GDB_PY_LL_ARG, &py_line))
178 return NULL;
179
492d29ea 180 TRY
bc79de95
PM
181 {
182 pcs = find_pcs_for_symtab_line (symtab, py_line, &best_entry);
183 }
492d29ea
PA
184 CATCH (except, RETURN_MASK_ALL)
185 {
186 GDB_PY_HANDLE_EXCEPTION (except);
187 }
188 END_CATCH
bc79de95
PM
189
190 tuple = build_line_table_tuple_from_pcs (py_line, pcs);
191 VEC_free (CORE_ADDR, pcs);
192
193 return tuple;
194}
195
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. */
199
200static PyObject *
201ltpy_has_line (PyObject *self, PyObject *args)
202{
203 struct symtab *symtab;
2a081c59 204 gdb_py_longest py_line;
bc79de95
PM
205 int index;
206
207 LTPY_REQUIRE_VALID (self, symtab);
208
209 if (! PyArg_ParseTuple (args, GDB_PY_LL_ARG, &py_line))
210 return NULL;
211
8435453b 212 if (SYMTAB_LINETABLE (symtab) == NULL)
bc79de95
PM
213 {
214 PyErr_SetString (PyExc_RuntimeError,
215 _("Linetable information not found in symbol table"));
216 return NULL;
217 }
218
8435453b 219 for (index = 0; index < SYMTAB_LINETABLE (symtab)->nitems; index++)
bc79de95 220 {
8435453b 221 struct linetable_entry *item = &(SYMTAB_LINETABLE (symtab)->item[index]);
bc79de95
PM
222 if (item->line == py_line)
223 Py_RETURN_TRUE;
224 }
225
226 Py_RETURN_FALSE;
227}
228
7b849db4
CS
229/* Implementation of gdb.LineTable.source_lines (self) -> List.
230 Returns a Python List that contains source line entries in the
bc79de95
PM
231 line table. This function will just return the source lines
232 without corresponding addresses. */
233
234static PyObject *
235ltpy_get_all_source_lines (PyObject *self, PyObject *args)
236{
237 struct symtab *symtab;
238 Py_ssize_t index;
239 PyObject *source_list, *source_dict, *line;
240 struct linetable_entry *item;
bc79de95
PM
241
242 LTPY_REQUIRE_VALID (self, symtab);
243
8435453b 244 if (SYMTAB_LINETABLE (symtab) == NULL)
bc79de95
PM
245 {
246 PyErr_SetString (PyExc_RuntimeError,
247 _("Linetable information not found in symbol table"));
248 return NULL;
249 }
250
251 source_dict = PyDict_New ();
252 if (source_dict == NULL)
253 return NULL;
254
8435453b 255 for (index = 0; index < SYMTAB_LINETABLE (symtab)->nitems; index++)
bc79de95 256 {
8435453b 257 item = &(SYMTAB_LINETABLE (symtab)->item[index]);
bc79de95
PM
258
259 /* 0 is used to signify end of line table information. Do not
260 include in the source set. */
261 if (item->line > 0)
262 {
263 line = gdb_py_object_from_longest (item->line);
264
265 if (line == NULL)
266 {
267 Py_DECREF (source_dict);
268 return NULL;
269 }
270
271 if (PyDict_SetItem (source_dict, line, Py_None) == -1)
272 {
273 Py_DECREF (line);
274 Py_DECREF (source_dict);
275 return NULL;
276 }
277
278 Py_DECREF (line);
279 }
280 }
281
282
283 source_list = PyDict_Keys (source_dict);
284 Py_DECREF (source_dict);
285
286 return source_list;
287}
288
4efd80aa 289/* Implementation of gdb.LineTable.is_valid (self) -> Boolean.
bc79de95
PM
290 Returns True if this line table object still exists in GDB. */
291
292static PyObject *
293ltpy_is_valid (PyObject *self, PyObject *args)
294{
295 struct symtab *symtab = NULL;
bc79de95
PM
296
297 symtab = symtab_object_to_symtab (get_symtab (self));
298
299 if (symtab == NULL)
300 Py_RETURN_FALSE;
301
302 Py_RETURN_TRUE;
303}
304
305/* Deconstructor for the line table object. Decrement the reference
306 to the symbol table object before calling the default free. */
307
308static void
309ltpy_dealloc (PyObject *self)
310{
311 linetable_object *obj = (linetable_object *) self;
312
313 Py_DECREF (obj->symtab);
314 Py_TYPE (self)->tp_free (self);
315}
316
317/* Initialize LineTable, LineTableEntry and LineTableIterator
318 objects. */
319
320int
321gdbpy_initialize_linetable (void)
322{
323 if (PyType_Ready (&linetable_object_type) < 0)
324 return -1;
325 if (PyType_Ready (&linetable_entry_object_type) < 0)
326 return -1;
327 if (PyType_Ready (&ltpy_iterator_object_type) < 0)
328 return -1;
329
330 Py_INCREF (&linetable_object_type);
331 Py_INCREF (&linetable_entry_object_type);
332 Py_INCREF (&ltpy_iterator_object_type);
333
334 if (gdb_pymodule_addobject (gdb_module, "LineTable",
335 (PyObject *) &linetable_object_type) < 0)
336 return -1;
337
338 if (gdb_pymodule_addobject (gdb_module, "LineTableEntry",
339 (PyObject *) &linetable_entry_object_type) < 0)
340 return -1;
341
342 if (gdb_pymodule_addobject (gdb_module, "LineTableIterator",
343 (PyObject *) &ltpy_iterator_object_type) < 0)
344 return -1;
345
346 return 0;
347}
348
4efd80aa 349/* LineTable entry object get functions. */
bc79de95
PM
350
351/* Implementation of gdb.LineTableEntry.line (self) -> Long. Returns
352 a long integer associated with the line table entry. */
353
354static PyObject *
355ltpy_entry_get_line (PyObject *self, void *closure)
356{
357 linetable_entry_object *obj = (linetable_entry_object *) self;
358
359 return gdb_py_object_from_longest (obj->line);
360}
361
362/* Implementation of gdb.LineTableEntry.pc (self) -> Long. Returns a
363 a long integer associated with the PC of the line table entry. */
364
365static PyObject *
366ltpy_entry_get_pc (PyObject *self, void *closure)
367{
368 linetable_entry_object *obj = (linetable_entry_object *) self;
369
370 return gdb_py_object_from_longest (obj->pc);
371}
372
4efd80aa 373/* LineTable iterator functions. */
bc79de95
PM
374
375/* Return a new line table iterator. */
376
377static PyObject *
378ltpy_iter (PyObject *self)
379{
380 ltpy_iterator_object *ltpy_iter_obj;
381 struct symtab *symtab = NULL;
382
383 LTPY_REQUIRE_VALID (self, symtab);
384
385 ltpy_iter_obj = PyObject_New (ltpy_iterator_object,
386 &ltpy_iterator_object_type);
387 if (ltpy_iter_obj == NULL)
388 return NULL;
389
390 ltpy_iter_obj->current_index = 0;
391 ltpy_iter_obj->source = self;
392
393 Py_INCREF (self);
394 return (PyObject *) ltpy_iter_obj;
395}
396
397static void
398ltpy_iterator_dealloc (PyObject *obj)
399{
400 ltpy_iterator_object *iter_obj = (ltpy_iterator_object *) obj;
401
402 Py_DECREF (iter_obj->source);
403}
404
405/* Return a reference to the line table iterator. */
406
407static PyObject *
408ltpy_iterator (PyObject *self)
409{
410 ltpy_iterator_object *iter_obj = (ltpy_iterator_object *) self;
411 struct symtab *symtab;
412
413 LTPY_REQUIRE_VALID (iter_obj->source, symtab);
414
415 Py_INCREF (self);
416 return self;
417}
418
419/* Return the next line table entry in the iteration through the line
420 table data structure. */
421
422static PyObject *
423ltpy_iternext (PyObject *self)
424{
425 ltpy_iterator_object *iter_obj = (ltpy_iterator_object *) self;
426 struct symtab *symtab;
bc79de95
PM
427 PyObject *obj;
428 struct linetable_entry *item;
429
430 LTPY_REQUIRE_VALID (iter_obj->source, symtab);
431
8435453b 432 if (iter_obj->current_index >= SYMTAB_LINETABLE (symtab)->nitems)
bc79de95
PM
433 goto stop_iteration;
434
8435453b 435 item = &(SYMTAB_LINETABLE (symtab)->item[iter_obj->current_index]);
bc79de95
PM
436
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)
440 {
441 iter_obj->current_index++;
442
443 /* Exit if the internal value is the last item in the line table. */
8435453b 444 if (iter_obj->current_index >= SYMTAB_LINETABLE (symtab)->nitems)
bc79de95 445 goto stop_iteration;
8435453b 446 item = &(SYMTAB_LINETABLE (symtab)->item[iter_obj->current_index]);
bc79de95
PM
447 }
448
449 obj = build_linetable_entry (item->line, item->pc);
450 iter_obj->current_index++;
451
452 return obj;
453
454 stop_iteration:
455 PyErr_SetNone (PyExc_StopIteration);
456 return NULL;
457}
458
4efd80aa 459/* Implementation of gdb.LineTableIterator.is_valid (self) -> Boolean.
bc79de95
PM
460 Returns True if this line table iterator object still exists in
461 GDB. */
462
463static PyObject *
464ltpy_iter_is_valid (PyObject *self, PyObject *args)
465{
466 struct symtab *symtab = NULL;
467 ltpy_iterator_object *iter_obj = (ltpy_iterator_object *) self;
468
469 symtab = symtab_object_to_symtab (get_symtab (iter_obj->source));
470
471 if (symtab == NULL)
472 Py_RETURN_FALSE;
473
474 Py_RETURN_TRUE;
475}
476
477\f
478
479static PyMethodDef linetable_object_methods[] = {
480 { "line", ltpy_get_pcs_for_line, METH_VARARGS,
481 "line (lineno) -> Tuple\n\
482Return executable locations for a given source line." },
483 { "has_line", ltpy_has_line, METH_VARARGS,
484 "has_line (lineno) -> Boolean\n\
485Return TRUE if this line has executable information, FALSE if not." },
486 { "source_lines", ltpy_get_all_source_lines, METH_NOARGS,
7b849db4
CS
487 "source_lines () -> List\n\
488Return a list of all executable source lines." },
bc79de95
PM
489 { "is_valid", ltpy_is_valid, METH_NOARGS,
490 "is_valid () -> Boolean.\n\
4efd80aa 491Return True if this LineTable is valid, False if not." },
bc79de95
PM
492 {NULL} /* Sentinel */
493};
494
e36122e9 495PyTypeObject linetable_object_type = {
bc79de95
PM
496 PyVarObject_HEAD_INIT (NULL, 0)
497 "gdb.LineTable", /*tp_name*/
498 sizeof (linetable_object), /*tp_basicsize*/
499 0, /*tp_itemsize*/
500 ltpy_dealloc, /*tp_dealloc*/
501 0, /*tp_print*/
502 0, /*tp_getattr*/
503 0, /*tp_setattr*/
504 0, /*tp_compare*/
505 0, /*tp_repr*/
506 0, /*tp_as_number*/
507 0, /*tp_as_sequence*/
508 0, /*tp_as_mapping*/
509 0, /*tp_hash */
510 0, /*tp_call*/
511 0, /*tp_str*/
512 0, /*tp_getattro*/
513 0, /*tp_setattro*/
514 0, /*tp_as_buffer*/
515 Py_TPFLAGS_DEFAULT, /*tp_flags*/
516 "GDB line table object", /* tp_doc */
517 0, /* tp_traverse */
518 0, /* tp_clear */
519 0, /* tp_richcompare */
520 0, /* tp_weaklistoffset */
521 ltpy_iter, /* tp_iter */
522 0, /* tp_iternext */
523 linetable_object_methods, /* tp_methods */
524 0, /* tp_members */
525 0, /* tp_getset */
526 0, /* tp_base */
527 0, /* tp_dict */
528 0, /* tp_descr_get */
529 0, /* tp_descr_set */
530 0, /* tp_dictoffset */
531 0, /* tp_init */
532 0, /* tp_alloc */
533};
534
535static PyMethodDef ltpy_iterator_methods[] = {
536 { "is_valid", ltpy_iter_is_valid, METH_NOARGS,
537 "is_valid () -> Boolean.\n\
4efd80aa 538Return True if this LineTable iterator is valid, False if not." },
bc79de95
PM
539 {NULL} /* Sentinel */
540};
541
e36122e9 542PyTypeObject ltpy_iterator_object_type = {
bc79de95
PM
543 PyVarObject_HEAD_INIT (NULL, 0)
544 "gdb.LineTableIterator", /*tp_name*/
545 sizeof (ltpy_iterator_object), /*tp_basicsize*/
546 0, /*tp_itemsize*/
547 ltpy_iterator_dealloc, /*tp_dealloc*/
548 0, /*tp_print*/
549 0, /*tp_getattr*/
550 0, /*tp_setattr*/
551 0, /*tp_compare*/
552 0, /*tp_repr*/
553 0, /*tp_as_number*/
554 0, /*tp_as_sequence*/
555 0, /*tp_as_mapping*/
556 0, /*tp_hash */
557 0, /*tp_call*/
558 0, /*tp_str*/
559 0, /*tp_getattro*/
560 0, /*tp_setattro*/
561 0, /*tp_as_buffer*/
562 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_ITER, /*tp_flags*/
563 "GDB line table iterator object", /*tp_doc */
564 0, /*tp_traverse */
565 0, /*tp_clear */
566 0, /*tp_richcompare */
567 0, /*tp_weaklistoffset */
568 ltpy_iterator, /*tp_iter */
569 ltpy_iternext, /*tp_iternext */
570 ltpy_iterator_methods /*tp_methods */
571};
572
573
574static 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 */
580};
581
e36122e9 582PyTypeObject linetable_entry_object_type = {
bc79de95
PM
583 PyVarObject_HEAD_INIT (NULL, 0)
584 "gdb.LineTableEntry", /*tp_name*/
585 sizeof (linetable_entry_object), /*tp_basicsize*/
586 0, /*tp_itemsize*/
587 0, /*tp_dealloc*/
588 0, /*tp_print*/
589 0, /*tp_getattr*/
590 0, /*tp_setattr*/
591 0, /*tp_compare*/
592 0, /*tp_repr*/
593 0, /*tp_as_number*/
594 0, /*tp_as_sequence*/
595 0, /*tp_as_mapping*/
596 0, /*tp_hash */
597 0, /*tp_call*/
598 0, /*tp_str*/
599 0, /*tp_getattro*/
600 0, /*tp_setattro*/
601 0, /*tp_as_buffer*/
602 Py_TPFLAGS_DEFAULT, /*tp_flags*/
603 "GDB line table entry object", /* tp_doc */
604 0, /* tp_traverse */
605 0, /* tp_clear */
606 0, /* tp_richcompare */
607 0, /* tp_weaklistoffset */
608 0, /* tp_iter */
609 0, /* tp_iternext */
610 0, /* tp_methods */
611 0, /* tp_members */
612 linetable_entry_object_getset, /* tp_getset */
613 0, /* tp_base */
614 0, /* tp_dict */
615 0, /* tp_descr_get */
616 0, /* tp_descr_set */
617 0, /* tp_dictoffset */
618 0, /* tp_init */
619 0, /* tp_alloc */
620};
This page took 0.326471 seconds and 4 git commands to generate.