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