xref: /netbsd-src/external/gpl3/gdb.old/dist/gdb/python/py-symtab.c (revision f4748aaa01faf324805f9747191535eb6600f82c)
1 /* Python interface to symbol tables.
2 
3    Copyright (C) 2008-2020 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 "charset.h"
22 #include "symtab.h"
23 #include "source.h"
24 #include "python-internal.h"
25 #include "objfiles.h"
26 #include "block.h"
27 
28 typedef struct stpy_symtab_object {
29   PyObject_HEAD
30   /* The GDB Symbol table structure.  */
31   struct symtab *symtab;
32   /* A symtab object is associated with an objfile, so keep track with
33      a doubly-linked list, rooted in the objfile.  This allows
34      invalidation of the underlying struct symtab when the objfile is
35      deleted.  */
36   struct stpy_symtab_object *prev;
37   struct stpy_symtab_object *next;
38 } symtab_object;
39 
40 extern PyTypeObject symtab_object_type
41     CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("symtab_object");
42 static const struct objfile_data *stpy_objfile_data_key;
43 
44 /* Require a valid symbol table.  All access to symtab_object->symtab
45    should be gated by this call.  */
46 #define STPY_REQUIRE_VALID(symtab_obj, symtab)		 \
47   do {							 \
48     symtab = symtab_object_to_symtab (symtab_obj);	 \
49     if (symtab == NULL)					 \
50       {							 \
51 	PyErr_SetString (PyExc_RuntimeError,		 \
52 			 _("Symbol Table is invalid.")); \
53 	return NULL;					 \
54       }							 \
55   } while (0)
56 
57 typedef struct salpy_sal_object {
58   PyObject_HEAD
59   /* The GDB Symbol table structure.  */
60   PyObject *symtab;
61   /* The GDB Symbol table and line structure.  */
62   struct symtab_and_line *sal;
63   /* A Symtab and line object is associated with an objfile, so keep
64      track with a doubly-linked list, rooted in the objfile.  This
65      allows invalidation of the underlying struct symtab_and_line
66      when the objfile is deleted.  */
67   struct salpy_sal_object *prev;
68   struct salpy_sal_object *next;
69 } sal_object;
70 
71 extern PyTypeObject sal_object_type
72     CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("sal_object");
73 static const struct objfile_data *salpy_objfile_data_key;
74 
75 /* Require a valid symbol table and line object.  All access to
76    sal_object->sal should be gated by this call.  */
77 #define SALPY_REQUIRE_VALID(sal_obj, sal)				\
78   do {									\
79     sal = sal_object_to_symtab_and_line (sal_obj);			\
80     if (sal == NULL)							\
81       {									\
82 	  PyErr_SetString (PyExc_RuntimeError,				\
83 			   _("Symbol Table and Line is invalid."));	\
84 	  return NULL;							\
85 	}								\
86   } while (0)
87 
88 static PyObject *
89 stpy_str (PyObject *self)
90 {
91   PyObject *result;
92   struct symtab *symtab = NULL;
93 
94   STPY_REQUIRE_VALID (self, symtab);
95 
96   result = PyString_FromString (symtab_to_filename_for_display (symtab));
97 
98   return result;
99 }
100 
101 static PyObject *
102 stpy_get_filename (PyObject *self, void *closure)
103 {
104   PyObject *str_obj;
105   struct symtab *symtab = NULL;
106   const char *filename;
107 
108   STPY_REQUIRE_VALID (self, symtab);
109   filename = symtab_to_filename_for_display (symtab);
110 
111   str_obj = host_string_to_python_string (filename).release ();
112   return str_obj;
113 }
114 
115 static PyObject *
116 stpy_get_objfile (PyObject *self, void *closure)
117 {
118   struct symtab *symtab = NULL;
119 
120   STPY_REQUIRE_VALID (self, symtab);
121 
122   return objfile_to_objfile_object (SYMTAB_OBJFILE (symtab)).release ();
123 }
124 
125 /* Getter function for symtab.producer.  */
126 
127 static PyObject *
128 stpy_get_producer (PyObject *self, void *closure)
129 {
130   struct symtab *symtab = NULL;
131   struct compunit_symtab *cust;
132 
133   STPY_REQUIRE_VALID (self, symtab);
134   cust = SYMTAB_COMPUNIT (symtab);
135   if (COMPUNIT_PRODUCER (cust) != NULL)
136     {
137       const char *producer = COMPUNIT_PRODUCER (cust);
138 
139       return host_string_to_python_string (producer).release ();
140     }
141 
142   Py_RETURN_NONE;
143 }
144 
145 static PyObject *
146 stpy_fullname (PyObject *self, PyObject *args)
147 {
148   const char *fullname;
149   struct symtab *symtab = NULL;
150 
151   STPY_REQUIRE_VALID (self, symtab);
152 
153   fullname = symtab_to_fullname (symtab);
154 
155   return host_string_to_python_string (fullname).release ();
156 }
157 
158 /* Implementation of gdb.Symtab.is_valid (self) -> Boolean.
159    Returns True if this Symbol table still exists in GDB.  */
160 
161 static PyObject *
162 stpy_is_valid (PyObject *self, PyObject *args)
163 {
164   struct symtab *symtab = NULL;
165 
166   symtab = symtab_object_to_symtab (self);
167   if (symtab == NULL)
168     Py_RETURN_FALSE;
169 
170   Py_RETURN_TRUE;
171 }
172 
173 /* Return the GLOBAL_BLOCK of the underlying symtab.  */
174 
175 static PyObject *
176 stpy_global_block (PyObject *self, PyObject *args)
177 {
178   struct symtab *symtab = NULL;
179   const struct block *block = NULL;
180   const struct blockvector *blockvector;
181 
182   STPY_REQUIRE_VALID (self, symtab);
183 
184   blockvector = SYMTAB_BLOCKVECTOR (symtab);
185   block = BLOCKVECTOR_BLOCK (blockvector, GLOBAL_BLOCK);
186   return block_to_block_object (block, SYMTAB_OBJFILE (symtab));
187 }
188 
189 /* Return the STATIC_BLOCK of the underlying symtab.  */
190 
191 static PyObject *
192 stpy_static_block (PyObject *self, PyObject *args)
193 {
194   struct symtab *symtab = NULL;
195   const struct block *block = NULL;
196   const struct blockvector *blockvector;
197 
198   STPY_REQUIRE_VALID (self, symtab);
199 
200   blockvector = SYMTAB_BLOCKVECTOR (symtab);
201   block = BLOCKVECTOR_BLOCK (blockvector, STATIC_BLOCK);
202   return block_to_block_object (block, SYMTAB_OBJFILE (symtab));
203 }
204 
205 /* Implementation of gdb.Symtab.linetable (self) -> gdb.LineTable.
206    Returns a gdb.LineTable object corresponding to this symbol
207    table.  */
208 
209 static PyObject *
210 stpy_get_linetable (PyObject *self, PyObject *args)
211 {
212   struct symtab *symtab = NULL;
213 
214   STPY_REQUIRE_VALID (self, symtab);
215 
216   return symtab_to_linetable_object (self);
217 }
218 
219 static PyObject *
220 salpy_str (PyObject *self)
221 {
222   const char *filename;
223   sal_object *sal_obj;
224   struct symtab_and_line *sal = NULL;
225 
226   SALPY_REQUIRE_VALID (self, sal);
227 
228   sal_obj = (sal_object *) self;
229   if (sal_obj->symtab == Py_None)
230     filename = "<unknown>";
231   else
232     {
233       symtab *symtab = symtab_object_to_symtab (sal_obj->symtab);
234       filename = symtab_to_filename_for_display (symtab);
235     }
236 
237   return PyString_FromFormat ("symbol and line for %s, line %d", filename,
238 			      sal->line);
239 }
240 
241 static void
242 stpy_dealloc (PyObject *obj)
243 {
244   symtab_object *symtab = (symtab_object *) obj;
245 
246   if (symtab->prev)
247     symtab->prev->next = symtab->next;
248   else if (symtab->symtab)
249     {
250       set_objfile_data (SYMTAB_OBJFILE (symtab->symtab),
251 			stpy_objfile_data_key, symtab->next);
252     }
253   if (symtab->next)
254     symtab->next->prev = symtab->prev;
255   symtab->symtab = NULL;
256   Py_TYPE (obj)->tp_free (obj);
257 }
258 
259 
260 static PyObject *
261 salpy_get_pc (PyObject *self, void *closure)
262 {
263   struct symtab_and_line *sal = NULL;
264 
265   SALPY_REQUIRE_VALID (self, sal);
266 
267   return gdb_py_long_from_ulongest (sal->pc);
268 }
269 
270 /* Implementation of the get method for the 'last' attribute of
271    gdb.Symtab_and_line.  */
272 
273 static PyObject *
274 salpy_get_last (PyObject *self, void *closure)
275 {
276   struct symtab_and_line *sal = NULL;
277 
278   SALPY_REQUIRE_VALID (self, sal);
279 
280   if (sal->end > 0)
281     return gdb_py_long_from_ulongest (sal->end - 1);
282   else
283     Py_RETURN_NONE;
284 }
285 
286 static PyObject *
287 salpy_get_line (PyObject *self, void *closure)
288 {
289   struct symtab_and_line *sal = NULL;
290 
291   SALPY_REQUIRE_VALID (self, sal);
292 
293   return PyInt_FromLong (sal->line);
294 }
295 
296 static PyObject *
297 salpy_get_symtab (PyObject *self, void *closure)
298 {
299   struct symtab_and_line *sal;
300   sal_object *self_sal = (sal_object *) self;
301 
302   SALPY_REQUIRE_VALID (self, sal);
303 
304   Py_INCREF (self_sal->symtab);
305 
306   return (PyObject *) self_sal->symtab;
307 }
308 
309 /* Implementation of gdb.Symtab_and_line.is_valid (self) -> Boolean.
310    Returns True if this Symbol table and line object still exists GDB.  */
311 
312 static PyObject *
313 salpy_is_valid (PyObject *self, PyObject *args)
314 {
315   struct symtab_and_line *sal;
316 
317   sal = sal_object_to_symtab_and_line (self);
318   if (sal == NULL)
319     Py_RETURN_FALSE;
320 
321   Py_RETURN_TRUE;
322 }
323 
324 static void
325 salpy_dealloc (PyObject *self)
326 {
327   sal_object *self_sal = (sal_object *) self;
328 
329   if (self_sal->prev)
330     self_sal->prev->next = self_sal->next;
331   else if (self_sal->symtab != Py_None)
332     set_objfile_data
333       (SYMTAB_OBJFILE (symtab_object_to_symtab (self_sal->symtab)),
334        salpy_objfile_data_key, self_sal->next);
335 
336   if (self_sal->next)
337     self_sal->next->prev = self_sal->prev;
338 
339   Py_DECREF (self_sal->symtab);
340   xfree (self_sal->sal);
341   Py_TYPE (self)->tp_free (self);
342 }
343 
344 /* Given a sal, and a sal_object that has previously been allocated
345    and initialized, populate the sal_object with the struct sal data.
346    Also, register the sal_object life-cycle with the life-cycle of the
347    object file associated with this sal, if needed.  If a failure
348    occurs during the sal population, this function will return -1.  */
349 static int CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION
350 set_sal (sal_object *sal_obj, struct symtab_and_line sal)
351 {
352   PyObject *symtab_obj;
353 
354   if (sal.symtab)
355     {
356       symtab_obj = symtab_to_symtab_object  (sal.symtab);
357       /* If a symtab existed in the sal, but it cannot be duplicated,
358 	 we exit.  */
359       if (symtab_obj == NULL)
360 	return -1;
361     }
362   else
363     {
364       symtab_obj = Py_None;
365       Py_INCREF (Py_None);
366     }
367 
368   sal_obj->sal = ((struct symtab_and_line *)
369 		  xmemdup (&sal, sizeof (struct symtab_and_line),
370 			   sizeof (struct symtab_and_line)));
371   sal_obj->symtab = symtab_obj;
372   sal_obj->prev = NULL;
373 
374   /* If the SAL does not have a symtab, we do not add it to the
375      objfile cleanup observer linked list.  */
376   if (sal_obj->symtab != Py_None)
377     {
378       symtab *symtab = symtab_object_to_symtab (sal_obj->symtab);
379 
380       sal_obj->next
381 	= ((struct salpy_sal_object *) objfile_data (SYMTAB_OBJFILE (symtab),
382 						     salpy_objfile_data_key));
383       if (sal_obj->next)
384 	sal_obj->next->prev = sal_obj;
385 
386       set_objfile_data (SYMTAB_OBJFILE (symtab),
387 			salpy_objfile_data_key, sal_obj);
388     }
389   else
390     sal_obj->next = NULL;
391 
392   return 0;
393 }
394 
395 /* Given a symtab, and a symtab_object that has previously been
396    allocated and initialized, populate the symtab_object with the
397    struct symtab data.  Also, register the symtab_object life-cycle
398    with the life-cycle of the object file associated with this
399    symtab, if needed.  */
400 static void
401 set_symtab (symtab_object *obj, struct symtab *symtab)
402 {
403   obj->symtab = symtab;
404   obj->prev = NULL;
405   if (symtab)
406     {
407       obj->next
408 	= ((struct stpy_symtab_object *)
409 	   objfile_data (SYMTAB_OBJFILE (symtab), stpy_objfile_data_key));
410       if (obj->next)
411 	obj->next->prev = obj;
412       set_objfile_data (SYMTAB_OBJFILE (symtab), stpy_objfile_data_key, obj);
413     }
414   else
415     obj->next = NULL;
416 }
417 
418 /* Create a new symbol table (gdb.Symtab) object that encapsulates the
419    symtab structure from GDB.  */
420 PyObject *
421 symtab_to_symtab_object (struct symtab *symtab)
422 {
423   symtab_object *symtab_obj;
424 
425   symtab_obj = PyObject_New (symtab_object, &symtab_object_type);
426   if (symtab_obj)
427     set_symtab (symtab_obj, symtab);
428 
429   return (PyObject *) symtab_obj;
430 }
431 
432 /* Create a new symtab and line (gdb.Symtab_and_line) object
433    that encapsulates the symtab_and_line structure from GDB.  */
434 PyObject *
435 symtab_and_line_to_sal_object (struct symtab_and_line sal)
436 {
437   gdbpy_ref<sal_object> sal_obj (PyObject_New (sal_object, &sal_object_type));
438   if (sal_obj != NULL)
439     {
440       if (set_sal (sal_obj.get (), sal) < 0)
441 	return NULL;
442     }
443 
444   return (PyObject *) sal_obj.release ();
445 }
446 
447 /* Return struct symtab_and_line reference that is wrapped by this
448    object.  */
449 struct symtab_and_line *
450 sal_object_to_symtab_and_line (PyObject *obj)
451 {
452   if (! PyObject_TypeCheck (obj, &sal_object_type))
453     return NULL;
454   return ((sal_object *) obj)->sal;
455 }
456 
457 /* Return struct symtab reference that is wrapped by this object.  */
458 struct symtab *
459 symtab_object_to_symtab (PyObject *obj)
460 {
461   if (! PyObject_TypeCheck (obj, &symtab_object_type))
462     return NULL;
463   return ((symtab_object *) obj)->symtab;
464 }
465 
466 /* This function is called when an objfile is about to be freed.
467    Invalidate the symbol table as further actions on the symbol table
468    would result in bad data.  All access to obj->symtab should be
469    gated by STPY_REQUIRE_VALID which will raise an exception on
470    invalid symbol tables.  */
471 static void
472 del_objfile_symtab (struct objfile *objfile, void *datum)
473 {
474   symtab_object *obj = (symtab_object *) datum;
475 
476   while (obj)
477     {
478       symtab_object *next = obj->next;
479 
480       obj->symtab = NULL;
481       obj->next = NULL;
482       obj->prev = NULL;
483       obj = next;
484     }
485 }
486 
487 /* This function is called when an objfile is about to be freed.
488    Invalidate the sal object as further actions on the sal
489    would result in bad data.  All access to obj->sal should be
490    gated by SALPY_REQUIRE_VALID which will raise an exception on
491    invalid symbol table and line objects.  */
492 static void
493 del_objfile_sal (struct objfile *objfile, void *datum)
494 {
495   sal_object *obj = (sal_object *) datum;
496 
497   while (obj)
498     {
499       sal_object *next = obj->next;
500 
501       gdbpy_ref<> tmp (obj->symtab);
502       obj->symtab = Py_None;
503       Py_INCREF (Py_None);
504 
505       obj->next = NULL;
506       obj->prev = NULL;
507       xfree (obj->sal);
508       obj->sal = NULL;
509 
510       obj = next;
511     }
512 }
513 
514 int
515 gdbpy_initialize_symtabs (void)
516 {
517   symtab_object_type.tp_new = PyType_GenericNew;
518   if (PyType_Ready (&symtab_object_type) < 0)
519     return -1;
520 
521   sal_object_type.tp_new = PyType_GenericNew;
522   if (PyType_Ready (&sal_object_type) < 0)
523     return -1;
524 
525   /* Register an objfile "free" callback so we can properly
526      invalidate symbol tables, and symbol table and line data
527      structures when an object file that is about to be
528      deleted.  */
529   stpy_objfile_data_key
530     = register_objfile_data_with_cleanup (NULL, del_objfile_symtab);
531   salpy_objfile_data_key
532     = register_objfile_data_with_cleanup (NULL, del_objfile_sal);
533 
534   if (gdb_pymodule_addobject (gdb_module, "Symtab",
535 			      (PyObject *) &symtab_object_type) < 0)
536     return -1;
537 
538   return gdb_pymodule_addobject (gdb_module, "Symtab_and_line",
539 				 (PyObject *) &sal_object_type);
540 }
541 
542 
543 
544 static gdb_PyGetSetDef symtab_object_getset[] = {
545   { "filename", stpy_get_filename, NULL,
546     "The symbol table's source filename.", NULL },
547   { "objfile", stpy_get_objfile, NULL, "The symtab's objfile.",
548     NULL },
549   { "producer", stpy_get_producer, NULL,
550     "The name/version of the program that compiled this symtab.", NULL },
551   {NULL}  /* Sentinel */
552 };
553 
554 static PyMethodDef symtab_object_methods[] = {
555   { "is_valid", stpy_is_valid, METH_NOARGS,
556     "is_valid () -> Boolean.\n\
557 Return true if this symbol table is valid, false if not." },
558   { "fullname", stpy_fullname, METH_NOARGS,
559     "fullname () -> String.\n\
560 Return the symtab's full source filename." },
561   { "global_block", stpy_global_block, METH_NOARGS,
562     "global_block () -> gdb.Block.\n\
563 Return the global block of the symbol table." },
564   { "static_block", stpy_static_block, METH_NOARGS,
565     "static_block () -> gdb.Block.\n\
566 Return the static block of the symbol table." },
567     { "linetable", stpy_get_linetable, METH_NOARGS,
568     "linetable () -> gdb.LineTable.\n\
569 Return the LineTable associated with this symbol table" },
570   {NULL}  /* Sentinel */
571 };
572 
573 PyTypeObject symtab_object_type = {
574   PyVarObject_HEAD_INIT (NULL, 0)
575   "gdb.Symtab",			  /*tp_name*/
576   sizeof (symtab_object),	  /*tp_basicsize*/
577   0,				  /*tp_itemsize*/
578   stpy_dealloc,			  /*tp_dealloc*/
579   0,				  /*tp_print*/
580   0,				  /*tp_getattr*/
581   0,				  /*tp_setattr*/
582   0,				  /*tp_compare*/
583   0,				  /*tp_repr*/
584   0,				  /*tp_as_number*/
585   0,				  /*tp_as_sequence*/
586   0,				  /*tp_as_mapping*/
587   0,				  /*tp_hash */
588   0,				  /*tp_call*/
589   stpy_str,			  /*tp_str*/
590   0,				  /*tp_getattro*/
591   0,				  /*tp_setattro*/
592   0,				  /*tp_as_buffer*/
593   Py_TPFLAGS_DEFAULT,		  /*tp_flags*/
594   "GDB symtab object",		  /*tp_doc */
595   0,				  /*tp_traverse */
596   0,				  /*tp_clear */
597   0,				  /*tp_richcompare */
598   0,				  /*tp_weaklistoffset */
599   0,				  /*tp_iter */
600   0,				  /*tp_iternext */
601   symtab_object_methods,	  /*tp_methods */
602   0,				  /*tp_members */
603   symtab_object_getset		  /*tp_getset */
604 };
605 
606 static gdb_PyGetSetDef sal_object_getset[] = {
607   { "symtab", salpy_get_symtab, NULL, "Symtab object.", NULL },
608   { "pc", salpy_get_pc, NULL, "Return the symtab_and_line's pc.", NULL },
609   { "last", salpy_get_last, NULL,
610     "Return the symtab_and_line's last address.", NULL },
611   { "line", salpy_get_line, NULL,
612     "Return the symtab_and_line's line.", NULL },
613   {NULL}  /* Sentinel */
614 };
615 
616 static PyMethodDef sal_object_methods[] = {
617   { "is_valid", salpy_is_valid, METH_NOARGS,
618     "is_valid () -> Boolean.\n\
619 Return true if this symbol table and line is valid, false if not." },
620   {NULL}  /* Sentinel */
621 };
622 
623 PyTypeObject sal_object_type = {
624   PyVarObject_HEAD_INIT (NULL, 0)
625   "gdb.Symtab_and_line",	  /*tp_name*/
626   sizeof (sal_object),		  /*tp_basicsize*/
627   0,				  /*tp_itemsize*/
628   salpy_dealloc,		  /*tp_dealloc*/
629   0,				  /*tp_print*/
630   0,				  /*tp_getattr*/
631   0,				  /*tp_setattr*/
632   0,				  /*tp_compare*/
633   0,				  /*tp_repr*/
634   0,				  /*tp_as_number*/
635   0,				  /*tp_as_sequence*/
636   0,				  /*tp_as_mapping*/
637   0,				  /*tp_hash */
638   0,				  /*tp_call*/
639   salpy_str,			  /*tp_str*/
640   0,				  /*tp_getattro*/
641   0,				  /*tp_setattro*/
642   0,				  /*tp_as_buffer*/
643   Py_TPFLAGS_DEFAULT,		  /*tp_flags*/
644   "GDB symtab_and_line object",	  /*tp_doc */
645   0,				  /*tp_traverse */
646   0,				  /*tp_clear */
647   0,				  /*tp_richcompare */
648   0,				  /*tp_weaklistoffset */
649   0,				  /*tp_iter */
650   0,				  /*tp_iternext */
651   sal_object_methods,		  /*tp_methods */
652   0,				  /*tp_members */
653   sal_object_getset		  /*tp_getset */
654 };
655