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