GDB (xrefs)
py-linetable.c
Go to the documentation of this file.
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. */
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;
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 */
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;
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 *
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 {
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 *
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
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 {
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 {
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 
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 };
static void ltpy_iterator_dealloc(PyObject *obj)
Definition: py-linetable.c:401
int gdb_pymodule_addobject(PyObject *module, const char *name, PyObject *object)
Definition: py-utils.c:437
PyObject_HEAD PyObject * symtab
Definition: py-linetable.c:39
#define Py_DECREF(op)
PyObject_HEAD int line
Definition: py-linetable.c:26
PyTypeObject linetable_entry_object_type CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF("linetable_entry_object")
bfd_vma CORE_ADDR
Definition: common-types.h:41
#define LTPY_REQUIRE_VALID(lt_obj, symtab)
Definition: py-linetable.c:69
PyObject_HEAD int current_index
Definition: py-linetable.c:48
static PyObject * build_line_table_tuple_from_pcs(int line, VEC(CORE_ADDR)*vec)
Definition: py-linetable.c:124
static PyObject * ltpy_get_all_source_lines(PyObject *self, PyObject *args)
Definition: py-linetable.c:236
static PyObject * ltpy_entry_get_pc(PyObject *self, void *closure)
Definition: py-linetable.c:369
#define VEC(T)
Definition: vec.h:398
PyObject * symtab_to_linetable_object(PyObject *symtab)
Definition: py-linetable.c:85
#define _(String)
Definition: gdb_locale.h:40
static PyObject * ltpy_get_pcs_for_line(PyObject *self, PyObject *args)
Definition: py-linetable.c:167
long gdb_py_longest
#define END_CATCH
#define GDB_PY_HANDLE_EXCEPTION(Exception)
static PyObject * ltpy_is_valid(PyObject *self, PyObject *args)
Definition: py-linetable.c:295
#define TRY
#define VEC_iterate(T, V, I, P)
Definition: vec.h:165
#define CATCH(EXCEPTION, MASK)
static PyObject * ltpy_entry_get_line(PyObject *self, void *closure)
Definition: py-linetable.c:358
CORE_ADDR pc
Definition: symtab.h:865
PyObject * gdb_py_object_from_longest(LONGEST l)
Definition: py-utils.c:360
struct symtab * symtab_object_to_symtab(PyObject *obj)
Definition: py-symtab.c:465
static PyObject * ltpy_iter(PyObject *self)
Definition: py-linetable.c:381
int struct linetable_entry ** best_entry
Definition: symtab.h:1571
#define VEC_length(T, V)
Definition: vec.h:124
Definition: symtab.h:862
Definition: symtab.h:925
#define GDB_PY_LL_ARG
static PyObject * ltpy_iternext(PyObject *self)
Definition: py-linetable.c:426
static PyObject * get_symtab(PyObject *linetable)
Definition: py-linetable.c:62
static void ltpy_dealloc(PyObject *self)
Definition: py-linetable.c:312
CORE_ADDR pc
Definition: py-linetable.c:28
static PyObject * ltpy_iterator(PyObject *self)
Definition: py-linetable.c:411
Definition: py-linetable.c:23
#define VEC_free(T, V)
Definition: vec.h:180
int line
Definition: symtab.h:1570
int gdbpy_initialize_linetable(void)
Definition: py-linetable.c:324
static PyObject * ltpy_iter_is_valid(PyObject *self, PyObject *args)
Definition: py-linetable.c:468
PyObject * gdb_module
Definition: python.c:112
int line
Definition: symtab.h:864
static PyObject * build_linetable_entry(int line, CORE_ADDR address)
Definition: py-linetable.c:102
static PyObject * ltpy_has_line(PyObject *self, PyObject *args)
Definition: py-linetable.c:202
#define SYMTAB_LINETABLE(symtab)
Definition: symtab.h:966
#define Py_TYPE(ob)
#define PyVarObject_HEAD_INIT(type, size)