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