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