]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gdb/python/py-symtab.c
9f7bdb0f132f931684cfa9f88f81ade5e714b4ac
[thirdparty/binutils-gdb.git] / gdb / python / py-symtab.c
1 /* Python interface to symbol tables.
2
3 Copyright (C) 2008-2025 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 "charset.h"
21 #include "symtab.h"
22 #include "source.h"
23 #include "python-internal.h"
24 #include "objfiles.h"
25 #include "block.h"
26
27 struct symtab_object {
28 PyObject_HEAD
29 /* The GDB Symbol table structure. */
30 struct symtab *symtab;
31 };
32
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;
37
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) \
41 do { \
42 symtab = symtab_object_to_symtab (symtab_obj); \
43 if (symtab == NULL) \
44 { \
45 PyErr_SetString (PyExc_RuntimeError, \
46 _("Symbol Table is invalid.")); \
47 return NULL; \
48 } \
49 } while (0)
50
51 struct sal_object {
52 PyObject_HEAD
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. */
59 sal_object *prev;
60 sal_object *next;
61 };
62
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
69 {
70 void operator() (sal_object *obj)
71 {
72 xfree (obj->sal);
73 obj->sal = nullptr;
74 }
75 };
76
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;
81
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) \
85 do { \
86 sal = sal_object_to_symtab_and_line (sal_obj); \
87 if (sal == NULL) \
88 { \
89 PyErr_SetString (PyExc_RuntimeError, \
90 _("Symbol Table and Line is invalid.")); \
91 return NULL; \
92 } \
93 } while (0)
94
95 static PyObject *
96 stpy_str (PyObject *self)
97 {
98 PyObject *result;
99 struct symtab *symtab = NULL;
100
101 STPY_REQUIRE_VALID (self, symtab);
102
103 result = PyUnicode_FromString (symtab_to_filename_for_display (symtab));
104
105 return result;
106 }
107
108 static PyObject *
109 stpy_get_filename (PyObject *self, void *closure)
110 {
111 PyObject *str_obj;
112 struct symtab *symtab = NULL;
113 const char *filename;
114
115 STPY_REQUIRE_VALID (self, symtab);
116 filename = symtab_to_filename_for_display (symtab);
117
118 str_obj = host_string_to_python_string (filename).release ();
119 return str_obj;
120 }
121
122 static PyObject *
123 stpy_get_objfile (PyObject *self, void *closure)
124 {
125 struct symtab *symtab = NULL;
126
127 STPY_REQUIRE_VALID (self, symtab);
128
129 return objfile_to_objfile_object (symtab->compunit ()->objfile ()).release ();
130 }
131
132 /* Getter function for symtab.producer. */
133
134 static PyObject *
135 stpy_get_producer (PyObject *self, void *closure)
136 {
137 struct symtab *symtab = NULL;
138 struct compunit_symtab *cust;
139
140 STPY_REQUIRE_VALID (self, symtab);
141 cust = symtab->compunit ();
142 if (cust->producer () != nullptr)
143 {
144 const char *producer = cust->producer ();
145
146 return host_string_to_python_string (producer).release ();
147 }
148
149 Py_RETURN_NONE;
150 }
151
152 static PyObject *
153 stpy_fullname (PyObject *self, PyObject *args)
154 {
155 const char *fullname;
156 struct symtab *symtab = NULL;
157
158 STPY_REQUIRE_VALID (self, symtab);
159
160 fullname = symtab_to_fullname (symtab);
161
162 return host_string_to_python_string (fullname).release ();
163 }
164
165 /* Implementation of gdb.Symtab.is_valid (self) -> Boolean.
166 Returns True if this Symbol table still exists in GDB. */
167
168 static PyObject *
169 stpy_is_valid (PyObject *self, PyObject *args)
170 {
171 struct symtab *symtab = NULL;
172
173 symtab = symtab_object_to_symtab (self);
174 if (symtab == NULL)
175 Py_RETURN_FALSE;
176
177 Py_RETURN_TRUE;
178 }
179
180 /* Return the GLOBAL_BLOCK of the underlying symtab. */
181
182 static PyObject *
183 stpy_global_block (PyObject *self, PyObject *args)
184 {
185 struct symtab *symtab = NULL;
186 const struct blockvector *blockvector;
187
188 STPY_REQUIRE_VALID (self, symtab);
189
190 blockvector = symtab->compunit ()->blockvector ();
191 const struct block *block = blockvector->global_block ();
192
193 return block_to_block_object (block, symtab->compunit ()->objfile ());
194 }
195
196 /* Return the STATIC_BLOCK of the underlying symtab. */
197
198 static PyObject *
199 stpy_static_block (PyObject *self, PyObject *args)
200 {
201 struct symtab *symtab = NULL;
202 const struct blockvector *blockvector;
203
204 STPY_REQUIRE_VALID (self, symtab);
205
206 blockvector = symtab->compunit ()->blockvector ();
207 const struct block *block = blockvector->static_block ();
208
209 return block_to_block_object (block, symtab->compunit ()->objfile ());
210 }
211
212 /* Implementation of gdb.Symtab.linetable (self) -> gdb.LineTable.
213 Returns a gdb.LineTable object corresponding to this symbol
214 table. */
215
216 static PyObject *
217 stpy_get_linetable (PyObject *self, PyObject *args)
218 {
219 struct symtab *symtab = NULL;
220
221 STPY_REQUIRE_VALID (self, symtab);
222
223 return symtab_to_linetable_object (self);
224 }
225
226 static PyObject *
227 salpy_str (PyObject *self)
228 {
229 const char *filename;
230 sal_object *sal_obj;
231 struct symtab_and_line *sal = nullptr;
232
233 SALPY_REQUIRE_VALID (self, sal);
234
235 sal_obj = (sal_object *) self;
236 if (sal_obj->sal->symtab == nullptr)
237 filename = "<unknown>";
238 else
239 filename = symtab_to_filename_for_display (sal_obj->sal->symtab);
240
241 return PyUnicode_FromFormat ("symbol and line for %s, line %d", filename,
242 sal->line);
243 }
244
245 static void
246 stpy_dealloc (PyObject *obj)
247 {
248 symtab_object *symtab_obj = (symtab_object *) obj;
249
250 if (symtab_obj->symtab != nullptr)
251 stpy_registry.remove (symtab_obj->symtab->compunit ()->objfile(),
252 symtab_obj);
253
254 Py_TYPE (obj)->tp_free (obj);
255 }
256
257
258 static PyObject *
259 salpy_get_pc (PyObject *self, void *closure)
260 {
261 struct symtab_and_line *sal = NULL;
262
263 SALPY_REQUIRE_VALID (self, sal);
264
265 return gdb_py_object_from_ulongest (sal->pc).release ();
266 }
267
268 /* Implementation of the get method for the 'last' attribute of
269 gdb.Symtab_and_line. */
270
271 static PyObject *
272 salpy_get_last (PyObject *self, void *closure)
273 {
274 struct symtab_and_line *sal = NULL;
275
276 SALPY_REQUIRE_VALID (self, sal);
277
278 if (sal->end > 0)
279 return gdb_py_object_from_ulongest (sal->end - 1).release ();
280 else
281 Py_RETURN_NONE;
282 }
283
284 static PyObject *
285 salpy_get_line (PyObject *self, void *closure)
286 {
287 struct symtab_and_line *sal = NULL;
288
289 SALPY_REQUIRE_VALID (self, sal);
290
291 return gdb_py_object_from_longest (sal->line).release ();
292 }
293
294 static PyObject *
295 salpy_get_symtab (PyObject *self, void *closure)
296 {
297 struct symtab_and_line *sal;
298
299 SALPY_REQUIRE_VALID (self, sal);
300
301 if (sal->symtab == nullptr)
302 Py_RETURN_NONE;
303 else
304 return symtab_to_symtab_object (sal->symtab);
305 }
306
307 /* Implementation of gdb.Symtab_and_line.is_valid (self) -> Boolean.
308 Returns True if this Symbol table and line object still exists GDB. */
309
310 static PyObject *
311 salpy_is_valid (PyObject *self, PyObject *args)
312 {
313 struct symtab_and_line *sal;
314
315 sal = sal_object_to_symtab_and_line (self);
316 if (sal == NULL)
317 Py_RETURN_FALSE;
318
319 Py_RETURN_TRUE;
320 }
321
322 static void
323 salpy_dealloc (PyObject *self)
324 {
325 sal_object *self_sal = (sal_object *) self;
326
327 if (self_sal->sal != nullptr && self_sal->sal->symtab != nullptr)
328 salpy_registry.remove (self_sal->sal->symtab->compunit ()->objfile (),
329 self_sal);
330
331 xfree (self_sal->sal);
332 Py_TYPE (self)->tp_free (self);
333 }
334
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. */
340 static void
341 set_sal (sal_object *sal_obj, struct symtab_and_line sal)
342 {
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;
348
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);
354 }
355
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. */
361 static void
362 set_symtab (symtab_object *obj, struct symtab *symtab)
363 {
364 obj->symtab = symtab;
365 if (symtab != nullptr)
366 stpy_registry.add (symtab->compunit ()->objfile (), obj);
367 }
368
369 /* Create a new symbol table (gdb.Symtab) object that encapsulates the
370 symtab structure from GDB. */
371 PyObject *
372 symtab_to_symtab_object (struct symtab *symtab)
373 {
374 symtab_object *symtab_obj;
375
376 /* Look if there's already a gdb.Symtab object for given SYMTAB
377 and if so, return it. */
378 if (symtab != nullptr)
379 {
380 symtab_obj = stpy_registry.lookup (symtab->compunit ()->objfile (),
381 symtab);
382 if (symtab_obj != nullptr)
383 return (PyObject*)symtab_obj;
384 }
385
386 symtab_obj = PyObject_New (symtab_object, &symtab_object_type);
387 if (symtab_obj)
388 set_symtab (symtab_obj, symtab);
389
390 return (PyObject *) symtab_obj;
391 }
392
393 /* Create a new symtab and line (gdb.Symtab_and_line) object
394 that encapsulates the symtab_and_line structure from GDB. */
395 PyObject *
396 symtab_and_line_to_sal_object (struct symtab_and_line sal)
397 {
398 sal_object *sal_obj;
399
400 sal_obj = PyObject_New (sal_object, &sal_object_type);
401 if (sal_obj != nullptr)
402 set_sal (sal_obj, sal);
403
404 return (PyObject *) sal_obj;
405 }
406
407 /* Return struct symtab_and_line reference that is wrapped by this
408 object. */
409 struct symtab_and_line *
410 sal_object_to_symtab_and_line (PyObject *obj)
411 {
412 if (! PyObject_TypeCheck (obj, &sal_object_type))
413 return NULL;
414 return ((sal_object *) obj)->sal;
415 }
416
417 /* Return struct symtab reference that is wrapped by this object. */
418 struct symtab *
419 symtab_object_to_symtab (PyObject *obj)
420 {
421 if (! PyObject_TypeCheck (obj, &symtab_object_type))
422 return NULL;
423 return ((symtab_object *) obj)->symtab;
424 }
425
426 static int CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION
427 gdbpy_initialize_symtabs (void)
428 {
429 symtab_object_type.tp_new = PyType_GenericNew;
430 if (gdbpy_type_ready (&symtab_object_type) < 0)
431 return -1;
432
433 sal_object_type.tp_new = PyType_GenericNew;
434 if (gdbpy_type_ready (&sal_object_type) < 0)
435 return -1;
436
437 return 0;
438 }
439
440 GDBPY_INITIALIZE_FILE (gdbpy_initialize_symtabs);
441
442 \f
443
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.",
448 NULL },
449 { "producer", stpy_get_producer, NULL,
450 "The name/version of the program that compiled this symtab.", NULL },
451 {NULL} /* Sentinel */
452 };
453
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 */
471 };
472
473 PyTypeObject symtab_object_type = {
474 PyVarObject_HEAD_INIT (NULL, 0)
475 "gdb.Symtab", /*tp_name*/
476 sizeof (symtab_object), /*tp_basicsize*/
477 0, /*tp_itemsize*/
478 stpy_dealloc, /*tp_dealloc*/
479 0, /*tp_print*/
480 0, /*tp_getattr*/
481 0, /*tp_setattr*/
482 0, /*tp_compare*/
483 0, /*tp_repr*/
484 0, /*tp_as_number*/
485 0, /*tp_as_sequence*/
486 0, /*tp_as_mapping*/
487 0, /*tp_hash */
488 0, /*tp_call*/
489 stpy_str, /*tp_str*/
490 0, /*tp_getattro*/
491 0, /*tp_setattro*/
492 0, /*tp_as_buffer*/
493 Py_TPFLAGS_DEFAULT, /*tp_flags*/
494 "GDB symtab object", /*tp_doc */
495 0, /*tp_traverse */
496 0, /*tp_clear */
497 0, /*tp_richcompare */
498 0, /*tp_weaklistoffset */
499 0, /*tp_iter */
500 0, /*tp_iternext */
501 symtab_object_methods, /*tp_methods */
502 0, /*tp_members */
503 symtab_object_getset /*tp_getset */
504 };
505
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 */
514 };
515
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 */
521 };
522
523 PyTypeObject sal_object_type = {
524 PyVarObject_HEAD_INIT (NULL, 0)
525 "gdb.Symtab_and_line", /*tp_name*/
526 sizeof (sal_object), /*tp_basicsize*/
527 0, /*tp_itemsize*/
528 salpy_dealloc, /*tp_dealloc*/
529 0, /*tp_print*/
530 0, /*tp_getattr*/
531 0, /*tp_setattr*/
532 0, /*tp_compare*/
533 0, /*tp_repr*/
534 0, /*tp_as_number*/
535 0, /*tp_as_sequence*/
536 0, /*tp_as_mapping*/
537 0, /*tp_hash */
538 0, /*tp_call*/
539 salpy_str, /*tp_str*/
540 0, /*tp_getattro*/
541 0, /*tp_setattro*/
542 0, /*tp_as_buffer*/
543 Py_TPFLAGS_DEFAULT, /*tp_flags*/
544 "GDB symtab_and_line object", /*tp_doc */
545 0, /*tp_traverse */
546 0, /*tp_clear */
547 0, /*tp_richcompare */
548 0, /*tp_weaklistoffset */
549 0, /*tp_iter */
550 0, /*tp_iternext */
551 sal_object_methods, /*tp_methods */
552 0, /*tp_members */
553 sal_object_getset /*tp_getset */
554 };