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