1 /* Python interface to symbol tables.
3 Copyright (C) 2008-2025 Free Software Foundation, Inc.
5 This file is part of GDB.
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.
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.
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/>. */
23 #include "python-internal.h"
27 struct symtab_object
{
29 /* The GDB Symbol table structure. */
30 struct symtab
*symtab
;
33 extern PyTypeObject symtab_object_type
34 CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("symtab_object");
35 static const gdbpy_registry
<gdbpy_memoizing_registry_storage
<symtab_object
,
36 symtab
, &symtab_object::symtab
>> stpy_registry
;
38 /* Require a valid symbol table. All access to symtab_object->symtab
39 should be gated by this call. */
40 #define STPY_REQUIRE_VALID(symtab_obj, symtab) \
42 symtab = symtab_object_to_symtab (symtab_obj); \
45 PyErr_SetString (PyExc_RuntimeError, \
46 _("Symbol Table is invalid.")); \
53 /* The GDB Symbol table and line structure. */
54 struct symtab_and_line
*sal
;
55 /* A Symtab and line object is associated with an objfile, so keep
56 track with a doubly-linked list, rooted in the objfile. This
57 allows invalidation of the underlying struct symtab_and_line
58 when the objfile is deleted. */
63 /* This is called when an objfile is about to be freed. Invalidate
64 the sal object as further actions on the sal would result in bad
65 data. All access to obj->sal should be gated by
66 SALPY_REQUIRE_VALID which will raise an exception on invalid symbol
67 table and line objects. */
68 struct salpy_invalidator
70 void operator() (sal_object
*obj
)
77 extern PyTypeObject sal_object_type
78 CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("sal_object");
79 static const gdbpy_registry
<gdbpy_tracking_registry_storage
<sal_object
,
80 symtab_and_line
, &sal_object::sal
, salpy_invalidator
>> salpy_registry
;
82 /* Require a valid symbol table and line object. All access to
83 sal_object->sal should be gated by this call. */
84 #define SALPY_REQUIRE_VALID(sal_obj, sal) \
86 sal = sal_object_to_symtab_and_line (sal_obj); \
89 PyErr_SetString (PyExc_RuntimeError, \
90 _("Symbol Table and Line is invalid.")); \
96 stpy_str (PyObject
*self
)
99 struct symtab
*symtab
= NULL
;
101 STPY_REQUIRE_VALID (self
, symtab
);
103 result
= PyUnicode_FromString (symtab_to_filename_for_display (symtab
));
109 stpy_get_filename (PyObject
*self
, void *closure
)
112 struct symtab
*symtab
= NULL
;
113 const char *filename
;
115 STPY_REQUIRE_VALID (self
, symtab
);
116 filename
= symtab_to_filename_for_display (symtab
);
118 str_obj
= host_string_to_python_string (filename
).release ();
123 stpy_get_objfile (PyObject
*self
, void *closure
)
125 struct symtab
*symtab
= NULL
;
127 STPY_REQUIRE_VALID (self
, symtab
);
129 return objfile_to_objfile_object (symtab
->compunit ()->objfile ()).release ();
132 /* Getter function for symtab.producer. */
135 stpy_get_producer (PyObject
*self
, void *closure
)
137 struct symtab
*symtab
= NULL
;
138 struct compunit_symtab
*cust
;
140 STPY_REQUIRE_VALID (self
, symtab
);
141 cust
= symtab
->compunit ();
142 if (cust
->producer () != nullptr)
144 const char *producer
= cust
->producer ();
146 return host_string_to_python_string (producer
).release ();
153 stpy_fullname (PyObject
*self
, PyObject
*args
)
155 const char *fullname
;
156 struct symtab
*symtab
= NULL
;
158 STPY_REQUIRE_VALID (self
, symtab
);
160 fullname
= symtab_to_fullname (symtab
);
162 return host_string_to_python_string (fullname
).release ();
165 /* Implementation of gdb.Symtab.is_valid (self) -> Boolean.
166 Returns True if this Symbol table still exists in GDB. */
169 stpy_is_valid (PyObject
*self
, PyObject
*args
)
171 struct symtab
*symtab
= NULL
;
173 symtab
= symtab_object_to_symtab (self
);
180 /* Return the GLOBAL_BLOCK of the underlying symtab. */
183 stpy_global_block (PyObject
*self
, PyObject
*args
)
185 struct symtab
*symtab
= NULL
;
186 const struct blockvector
*blockvector
;
188 STPY_REQUIRE_VALID (self
, symtab
);
190 blockvector
= symtab
->compunit ()->blockvector ();
191 const struct block
*block
= blockvector
->global_block ();
193 return block_to_block_object (block
, symtab
->compunit ()->objfile ());
196 /* Return the STATIC_BLOCK of the underlying symtab. */
199 stpy_static_block (PyObject
*self
, PyObject
*args
)
201 struct symtab
*symtab
= NULL
;
202 const struct blockvector
*blockvector
;
204 STPY_REQUIRE_VALID (self
, symtab
);
206 blockvector
= symtab
->compunit ()->blockvector ();
207 const struct block
*block
= blockvector
->static_block ();
209 return block_to_block_object (block
, symtab
->compunit ()->objfile ());
212 /* Implementation of gdb.Symtab.linetable (self) -> gdb.LineTable.
213 Returns a gdb.LineTable object corresponding to this symbol
217 stpy_get_linetable (PyObject
*self
, PyObject
*args
)
219 struct symtab
*symtab
= NULL
;
221 STPY_REQUIRE_VALID (self
, symtab
);
223 return symtab_to_linetable_object (self
);
227 salpy_str (PyObject
*self
)
229 const char *filename
;
231 struct symtab_and_line
*sal
= nullptr;
233 SALPY_REQUIRE_VALID (self
, sal
);
235 sal_obj
= (sal_object
*) self
;
236 if (sal_obj
->sal
->symtab
== nullptr)
237 filename
= "<unknown>";
239 filename
= symtab_to_filename_for_display (sal_obj
->sal
->symtab
);
241 return PyUnicode_FromFormat ("symbol and line for %s, line %d", filename
,
246 stpy_dealloc (PyObject
*obj
)
248 symtab_object
*symtab_obj
= (symtab_object
*) obj
;
250 if (symtab_obj
->symtab
!= nullptr)
251 stpy_registry
.remove (symtab_obj
->symtab
->compunit ()->objfile(),
254 Py_TYPE (obj
)->tp_free (obj
);
259 salpy_get_pc (PyObject
*self
, void *closure
)
261 struct symtab_and_line
*sal
= NULL
;
263 SALPY_REQUIRE_VALID (self
, sal
);
265 return gdb_py_object_from_ulongest (sal
->pc
).release ();
268 /* Implementation of the get method for the 'last' attribute of
269 gdb.Symtab_and_line. */
272 salpy_get_last (PyObject
*self
, void *closure
)
274 struct symtab_and_line
*sal
= NULL
;
276 SALPY_REQUIRE_VALID (self
, sal
);
279 return gdb_py_object_from_ulongest (sal
->end
- 1).release ();
285 salpy_get_line (PyObject
*self
, void *closure
)
287 struct symtab_and_line
*sal
= NULL
;
289 SALPY_REQUIRE_VALID (self
, sal
);
291 return gdb_py_object_from_longest (sal
->line
).release ();
295 salpy_get_symtab (PyObject
*self
, void *closure
)
297 struct symtab_and_line
*sal
;
299 SALPY_REQUIRE_VALID (self
, sal
);
301 if (sal
->symtab
== nullptr)
304 return symtab_to_symtab_object (sal
->symtab
);
307 /* Implementation of gdb.Symtab_and_line.is_valid (self) -> Boolean.
308 Returns True if this Symbol table and line object still exists GDB. */
311 salpy_is_valid (PyObject
*self
, PyObject
*args
)
313 struct symtab_and_line
*sal
;
315 sal
= sal_object_to_symtab_and_line (self
);
323 salpy_dealloc (PyObject
*self
)
325 sal_object
*self_sal
= (sal_object
*) self
;
327 if (self_sal
->sal
!= nullptr && self_sal
->sal
->symtab
!= nullptr)
328 salpy_registry
.remove (self_sal
->sal
->symtab
->compunit ()->objfile (),
331 xfree (self_sal
->sal
);
332 Py_TYPE (self
)->tp_free (self
);
335 /* Given a sal, and a sal_object that has previously been allocated
336 and initialized, populate the sal_object with the struct sal data.
337 Also, register the sal_object life-cycle with the life-cycle of the
338 object file associated with this sal, if needed. If a failure
339 occurs during the sal population, this function will return -1. */
341 set_sal (sal_object
*sal_obj
, struct symtab_and_line sal
)
343 sal_obj
->sal
= ((struct symtab_and_line
*)
344 xmemdup (&sal
, sizeof (struct symtab_and_line
),
345 sizeof (struct symtab_and_line
)));
346 sal_obj
->prev
= nullptr;
347 sal_obj
->next
= nullptr;
349 /* If the SAL does not have a symtab, we do not add it to the
350 objfile cleanup observer linked list. */
351 symtab
*symtab
= sal_obj
->sal
->symtab
;
352 if (symtab
!= nullptr)
353 salpy_registry
.add (symtab
->compunit ()->objfile (), sal_obj
);
356 /* Given a symtab, and a symtab_object that has previously been
357 allocated and initialized, populate the symtab_object with the
358 struct symtab data. Also, register the symtab_object life-cycle
359 with the life-cycle of the object file associated with this
360 symtab, if needed. */
362 set_symtab (symtab_object
*obj
, struct symtab
*symtab
)
364 obj
->symtab
= symtab
;
365 if (symtab
!= nullptr)
366 stpy_registry
.add (symtab
->compunit ()->objfile (), obj
);
369 /* Create a new symbol table (gdb.Symtab) object that encapsulates the
370 symtab structure from GDB. */
372 symtab_to_symtab_object (struct symtab
*symtab
)
374 symtab_object
*symtab_obj
;
376 /* Look if there's already a gdb.Symtab object for given SYMTAB
377 and if so, return it. */
378 if (symtab
!= nullptr)
380 symtab_obj
= stpy_registry
.lookup (symtab
->compunit ()->objfile (),
382 if (symtab_obj
!= nullptr)
383 return (PyObject
*)symtab_obj
;
386 symtab_obj
= PyObject_New (symtab_object
, &symtab_object_type
);
388 set_symtab (symtab_obj
, symtab
);
390 return (PyObject
*) symtab_obj
;
393 /* Create a new symtab and line (gdb.Symtab_and_line) object
394 that encapsulates the symtab_and_line structure from GDB. */
396 symtab_and_line_to_sal_object (struct symtab_and_line sal
)
400 sal_obj
= PyObject_New (sal_object
, &sal_object_type
);
401 if (sal_obj
!= nullptr)
402 set_sal (sal_obj
, sal
);
404 return (PyObject
*) sal_obj
;
407 /* Return struct symtab_and_line reference that is wrapped by this
409 struct symtab_and_line
*
410 sal_object_to_symtab_and_line (PyObject
*obj
)
412 if (! PyObject_TypeCheck (obj
, &sal_object_type
))
414 return ((sal_object
*) obj
)->sal
;
417 /* Return struct symtab reference that is wrapped by this object. */
419 symtab_object_to_symtab (PyObject
*obj
)
421 if (! PyObject_TypeCheck (obj
, &symtab_object_type
))
423 return ((symtab_object
*) obj
)->symtab
;
426 static int CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION
427 gdbpy_initialize_symtabs (void)
429 symtab_object_type
.tp_new
= PyType_GenericNew
;
430 if (gdbpy_type_ready (&symtab_object_type
) < 0)
433 sal_object_type
.tp_new
= PyType_GenericNew
;
434 if (gdbpy_type_ready (&sal_object_type
) < 0)
440 GDBPY_INITIALIZE_FILE (gdbpy_initialize_symtabs
);
444 static gdb_PyGetSetDef symtab_object_getset
[] = {
445 { "filename", stpy_get_filename
, NULL
,
446 "The symbol table's source filename.", NULL
},
447 { "objfile", stpy_get_objfile
, NULL
, "The symtab's objfile.",
449 { "producer", stpy_get_producer
, NULL
,
450 "The name/version of the program that compiled this symtab.", NULL
},
451 {NULL
} /* Sentinel */
454 static PyMethodDef symtab_object_methods
[] = {
455 { "is_valid", stpy_is_valid
, METH_NOARGS
,
456 "is_valid () -> Boolean.\n\
457 Return true if this symbol table is valid, false if not." },
458 { "fullname", stpy_fullname
, METH_NOARGS
,
459 "fullname () -> String.\n\
460 Return the symtab's full source filename." },
461 { "global_block", stpy_global_block
, METH_NOARGS
,
462 "global_block () -> gdb.Block.\n\
463 Return the global block of the symbol table." },
464 { "static_block", stpy_static_block
, METH_NOARGS
,
465 "static_block () -> gdb.Block.\n\
466 Return the static block of the symbol table." },
467 { "linetable", stpy_get_linetable
, METH_NOARGS
,
468 "linetable () -> gdb.LineTable.\n\
469 Return the LineTable associated with this symbol table" },
470 {NULL
} /* Sentinel */
473 PyTypeObject symtab_object_type
= {
474 PyVarObject_HEAD_INIT (NULL
, 0)
475 "gdb.Symtab", /*tp_name*/
476 sizeof (symtab_object
), /*tp_basicsize*/
478 stpy_dealloc
, /*tp_dealloc*/
485 0, /*tp_as_sequence*/
493 Py_TPFLAGS_DEFAULT
, /*tp_flags*/
494 "GDB symtab object", /*tp_doc */
497 0, /*tp_richcompare */
498 0, /*tp_weaklistoffset */
501 symtab_object_methods
, /*tp_methods */
503 symtab_object_getset
/*tp_getset */
506 static gdb_PyGetSetDef sal_object_getset
[] = {
507 { "symtab", salpy_get_symtab
, NULL
, "Symtab object.", NULL
},
508 { "pc", salpy_get_pc
, NULL
, "Return the symtab_and_line's pc.", NULL
},
509 { "last", salpy_get_last
, NULL
,
510 "Return the symtab_and_line's last address.", NULL
},
511 { "line", salpy_get_line
, NULL
,
512 "Return the symtab_and_line's line.", NULL
},
513 {NULL
} /* Sentinel */
516 static PyMethodDef sal_object_methods
[] = {
517 { "is_valid", salpy_is_valid
, METH_NOARGS
,
518 "is_valid () -> Boolean.\n\
519 Return true if this symbol table and line is valid, false if not." },
520 {NULL
} /* Sentinel */
523 PyTypeObject sal_object_type
= {
524 PyVarObject_HEAD_INIT (NULL
, 0)
525 "gdb.Symtab_and_line", /*tp_name*/
526 sizeof (sal_object
), /*tp_basicsize*/
528 salpy_dealloc
, /*tp_dealloc*/
535 0, /*tp_as_sequence*/
539 salpy_str
, /*tp_str*/
543 Py_TPFLAGS_DEFAULT
, /*tp_flags*/
544 "GDB symtab_and_line object", /*tp_doc */
547 0, /*tp_richcompare */
548 0, /*tp_weaklistoffset */
551 sal_object_methods
, /*tp_methods */
553 sal_object_getset
/*tp_getset */