]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gdb/python/py-linetable.c
symtab.h (SYMTAB_LINETABLE): Renamed from LINETABLE. All uses updated.
[thirdparty/binutils-gdb.git] / gdb / python / py-linetable.c
1 /* Python interface to line tables.
2
3 Copyright (C) 2013-2014 Free Software Foundation, Inc.
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"
22
23 typedef 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
31 static PyTypeObject linetable_entry_object_type
32 CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("linetable_entry_object");
33
34 typedef 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
42 static PyTypeObject linetable_object_type
43 CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("linetable_object");
44
45 typedef 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
55 static PyTypeObject ltpy_iterator_object_type
56 CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("ltpy_iterator_object");
57
58 /* Internal helper function to extract gdb.Symtab from a gdb.Linetable
59 object. */
60
61 static PyObject *
62 get_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
84 PyObject *
85 symtab_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
101 static PyObject *
102 build_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
123 static PyObject *
124 build_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
166 static PyObject *
167 ltpy_get_pcs_for_line (PyObject *self, PyObject *args)
168 {
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;
174 PyObject *tuple;
175 volatile struct gdb_exception except;
176
177 LTPY_REQUIRE_VALID (self, symtab);
178
179 if (! PyArg_ParseTuple (args, GDB_PY_LL_ARG, &py_line))
180 return NULL;
181
182 TRY_CATCH (except, RETURN_MASK_ALL)
183 {
184 pcs = find_pcs_for_symtab_line (symtab, py_line, &best_entry);
185 }
186 GDB_PY_HANDLE_EXCEPTION (except);
187
188 tuple = build_line_table_tuple_from_pcs (py_line, pcs);
189 VEC_free (CORE_ADDR, pcs);
190
191 return tuple;
192 }
193
194 /* Implementation of gdb.LineTable.has_line (self, line) -> Boolean.
195 Returns a Python Boolean indicating whether a source line has any
196 line table entries corresponding to it. */
197
198 static PyObject *
199 ltpy_has_line (PyObject *self, PyObject *args)
200 {
201 struct symtab *symtab;
202 gdb_py_longest py_line;
203 int index;
204
205 LTPY_REQUIRE_VALID (self, symtab);
206
207 if (! PyArg_ParseTuple (args, GDB_PY_LL_ARG, &py_line))
208 return NULL;
209
210 if (SYMTAB_LINETABLE (symtab) == NULL)
211 {
212 PyErr_SetString (PyExc_RuntimeError,
213 _("Linetable information not found in symbol table"));
214 return NULL;
215 }
216
217 for (index = 0; index < SYMTAB_LINETABLE (symtab)->nitems; index++)
218 {
219 struct linetable_entry *item = &(SYMTAB_LINETABLE (symtab)->item[index]);
220 if (item->line == py_line)
221 Py_RETURN_TRUE;
222 }
223
224 Py_RETURN_FALSE;
225 }
226
227 /* Implementation of gdb.LineTable.source_lines (self) -> FrozenSet.
228 Returns a Python FrozenSet that contains source line entries in the
229 line table. This function will just return the source lines
230 without corresponding addresses. */
231
232 static PyObject *
233 ltpy_get_all_source_lines (PyObject *self, PyObject *args)
234 {
235 struct symtab *symtab;
236 Py_ssize_t index;
237 PyObject *source_list, *source_dict, *line;
238 struct linetable_entry *item;
239 Py_ssize_t list_size;
240
241 LTPY_REQUIRE_VALID (self, symtab);
242
243 if (SYMTAB_LINETABLE (symtab) == NULL)
244 {
245 PyErr_SetString (PyExc_RuntimeError,
246 _("Linetable information not found in symbol table"));
247 return NULL;
248 }
249
250 source_dict = PyDict_New ();
251 if (source_dict == NULL)
252 return NULL;
253
254 for (index = 0; index < SYMTAB_LINETABLE (symtab)->nitems; index++)
255 {
256 item = &(SYMTAB_LINETABLE (symtab)->item[index]);
257
258 /* 0 is used to signify end of line table information. Do not
259 include in the source set. */
260 if (item->line > 0)
261 {
262 line = gdb_py_object_from_longest (item->line);
263
264 if (line == NULL)
265 {
266 Py_DECREF (source_dict);
267 return NULL;
268 }
269
270 if (PyDict_SetItem (source_dict, line, Py_None) == -1)
271 {
272 Py_DECREF (line);
273 Py_DECREF (source_dict);
274 return NULL;
275 }
276
277 Py_DECREF (line);
278 }
279 }
280
281
282 source_list = PyDict_Keys (source_dict);
283 Py_DECREF (source_dict);
284
285 return source_list;
286 }
287
288 /* Implementation of gdb.Linetable.is_valid (self) -> Boolean.
289 Returns True if this line table object still exists in GDB. */
290
291 static PyObject *
292 ltpy_is_valid (PyObject *self, PyObject *args)
293 {
294 struct symtab *symtab = NULL;
295 linetable_object *obj = (linetable_object *) self;
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
308 static void
309 ltpy_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
320 int
321 gdbpy_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
349 /* Linetable entry object get functions. */
350
351 /* Implementation of gdb.LineTableEntry.line (self) -> Long. Returns
352 a long integer associated with the line table entry. */
353
354 static PyObject *
355 ltpy_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
365 static PyObject *
366 ltpy_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
373 /* Linetable iterator functions. */
374
375 /* Return a new line table iterator. */
376
377 static PyObject *
378 ltpy_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
397 static void
398 ltpy_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
407 static PyObject *
408 ltpy_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
422 static PyObject *
423 ltpy_iternext (PyObject *self)
424 {
425 ltpy_iterator_object *iter_obj = (ltpy_iterator_object *) self;
426 struct symtab *symtab;
427 int index;
428 PyObject *obj;
429 struct linetable_entry *item;
430
431 LTPY_REQUIRE_VALID (iter_obj->source, symtab);
432
433 if (iter_obj->current_index >= SYMTAB_LINETABLE (symtab)->nitems)
434 goto stop_iteration;
435
436 item = &(SYMTAB_LINETABLE (symtab)->item[iter_obj->current_index]);
437
438 /* Skip over internal entries such as 0. 0 signifies the end of
439 line table data and is not useful to the API user. */
440 while (item->line < 1)
441 {
442 iter_obj->current_index++;
443
444 /* Exit if the internal value is the last item in the line table. */
445 if (iter_obj->current_index >= SYMTAB_LINETABLE (symtab)->nitems)
446 goto stop_iteration;
447 item = &(SYMTAB_LINETABLE (symtab)->item[iter_obj->current_index]);
448 }
449
450 obj = build_linetable_entry (item->line, item->pc);
451 iter_obj->current_index++;
452
453 return obj;
454
455 stop_iteration:
456 PyErr_SetNone (PyExc_StopIteration);
457 return NULL;
458 }
459
460 /* Implementation of gdb.LinetableIterator.is_valid (self) -> Boolean.
461 Returns True if this line table iterator object still exists in
462 GDB. */
463
464 static PyObject *
465 ltpy_iter_is_valid (PyObject *self, PyObject *args)
466 {
467 struct symtab *symtab = NULL;
468 ltpy_iterator_object *iter_obj = (ltpy_iterator_object *) self;
469
470 symtab = symtab_object_to_symtab (get_symtab (iter_obj->source));
471
472 if (symtab == NULL)
473 Py_RETURN_FALSE;
474
475 Py_RETURN_TRUE;
476 }
477
478 \f
479
480 static PyMethodDef linetable_object_methods[] = {
481 { "line", ltpy_get_pcs_for_line, METH_VARARGS,
482 "line (lineno) -> Tuple\n\
483 Return executable locations for a given source line." },
484 { "has_line", ltpy_has_line, METH_VARARGS,
485 "has_line (lineno) -> Boolean\n\
486 Return TRUE if this line has executable information, FALSE if not." },
487 { "source_lines", ltpy_get_all_source_lines, METH_NOARGS,
488 "source_lines () -> FrozenSet\n\
489 Return a frozen set of all executable source lines." },
490 { "is_valid", ltpy_is_valid, METH_NOARGS,
491 "is_valid () -> Boolean.\n\
492 Return True if this Linetable is valid, False if not." },
493 {NULL} /* Sentinel */
494 };
495
496 static PyTypeObject linetable_object_type = {
497 PyVarObject_HEAD_INIT (NULL, 0)
498 "gdb.LineTable", /*tp_name*/
499 sizeof (linetable_object), /*tp_basicsize*/
500 0, /*tp_itemsize*/
501 ltpy_dealloc, /*tp_dealloc*/
502 0, /*tp_print*/
503 0, /*tp_getattr*/
504 0, /*tp_setattr*/
505 0, /*tp_compare*/
506 0, /*tp_repr*/
507 0, /*tp_as_number*/
508 0, /*tp_as_sequence*/
509 0, /*tp_as_mapping*/
510 0, /*tp_hash */
511 0, /*tp_call*/
512 0, /*tp_str*/
513 0, /*tp_getattro*/
514 0, /*tp_setattro*/
515 0, /*tp_as_buffer*/
516 Py_TPFLAGS_DEFAULT, /*tp_flags*/
517 "GDB line table object", /* tp_doc */
518 0, /* tp_traverse */
519 0, /* tp_clear */
520 0, /* tp_richcompare */
521 0, /* tp_weaklistoffset */
522 ltpy_iter, /* tp_iter */
523 0, /* tp_iternext */
524 linetable_object_methods, /* tp_methods */
525 0, /* tp_members */
526 0, /* tp_getset */
527 0, /* tp_base */
528 0, /* tp_dict */
529 0, /* tp_descr_get */
530 0, /* tp_descr_set */
531 0, /* tp_dictoffset */
532 0, /* tp_init */
533 0, /* tp_alloc */
534 };
535
536 static PyMethodDef ltpy_iterator_methods[] = {
537 { "is_valid", ltpy_iter_is_valid, METH_NOARGS,
538 "is_valid () -> Boolean.\n\
539 Return True if this Linetable iterator is valid, False if not." },
540 {NULL} /* Sentinel */
541 };
542
543 static PyTypeObject ltpy_iterator_object_type = {
544 PyVarObject_HEAD_INIT (NULL, 0)
545 "gdb.LineTableIterator", /*tp_name*/
546 sizeof (ltpy_iterator_object), /*tp_basicsize*/
547 0, /*tp_itemsize*/
548 ltpy_iterator_dealloc, /*tp_dealloc*/
549 0, /*tp_print*/
550 0, /*tp_getattr*/
551 0, /*tp_setattr*/
552 0, /*tp_compare*/
553 0, /*tp_repr*/
554 0, /*tp_as_number*/
555 0, /*tp_as_sequence*/
556 0, /*tp_as_mapping*/
557 0, /*tp_hash */
558 0, /*tp_call*/
559 0, /*tp_str*/
560 0, /*tp_getattro*/
561 0, /*tp_setattro*/
562 0, /*tp_as_buffer*/
563 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_ITER, /*tp_flags*/
564 "GDB line table iterator object", /*tp_doc */
565 0, /*tp_traverse */
566 0, /*tp_clear */
567 0, /*tp_richcompare */
568 0, /*tp_weaklistoffset */
569 ltpy_iterator, /*tp_iter */
570 ltpy_iternext, /*tp_iternext */
571 ltpy_iterator_methods /*tp_methods */
572 };
573
574
575 static PyGetSetDef linetable_entry_object_getset[] = {
576 { "line", ltpy_entry_get_line, NULL,
577 "The line number in the source file.", NULL },
578 { "pc", ltpy_entry_get_pc, NULL,
579 "The memory address for this line number.", NULL },
580 { NULL } /* Sentinel */
581 };
582
583 static PyTypeObject linetable_entry_object_type = {
584 PyVarObject_HEAD_INIT (NULL, 0)
585 "gdb.LineTableEntry", /*tp_name*/
586 sizeof (linetable_entry_object), /*tp_basicsize*/
587 0, /*tp_itemsize*/
588 0, /*tp_dealloc*/
589 0, /*tp_print*/
590 0, /*tp_getattr*/
591 0, /*tp_setattr*/
592 0, /*tp_compare*/
593 0, /*tp_repr*/
594 0, /*tp_as_number*/
595 0, /*tp_as_sequence*/
596 0, /*tp_as_mapping*/
597 0, /*tp_hash */
598 0, /*tp_call*/
599 0, /*tp_str*/
600 0, /*tp_getattro*/
601 0, /*tp_setattro*/
602 0, /*tp_as_buffer*/
603 Py_TPFLAGS_DEFAULT, /*tp_flags*/
604 "GDB line table entry object", /* tp_doc */
605 0, /* tp_traverse */
606 0, /* tp_clear */
607 0, /* tp_richcompare */
608 0, /* tp_weaklistoffset */
609 0, /* tp_iter */
610 0, /* tp_iternext */
611 0, /* tp_methods */
612 0, /* tp_members */
613 linetable_entry_object_getset, /* tp_getset */
614 0, /* tp_base */
615 0, /* tp_dict */
616 0, /* tp_descr_get */
617 0, /* tp_descr_set */
618 0, /* tp_dictoffset */
619 0, /* tp_init */
620 0, /* tp_alloc */
621 };