Regenerate AArch64 opcodes files
[binutils-gdb.git] / gdb / python / py-block.c
blob9417ebc252e9d0f936f99be61989da84910ed943
1 /* Python interface to blocks.
3 Copyright (C) 2008-2024 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/>. */
20 #include "defs.h"
21 #include "block.h"
22 #include "dictionary.h"
23 #include "symtab.h"
24 #include "python-internal.h"
25 #include "objfiles.h"
27 struct block_object {
28 PyObject_HEAD
29 /* The GDB block structure that represents a frame's code block. */
30 const struct block *block;
31 /* The backing object file. There is no direct relationship in GDB
32 between a block and an object file. When a block is created also
33 store a pointer to the object file for later use. */
34 struct objfile *objfile;
35 /* Keep track of all blocks with a doubly-linked list. Needed for
36 block invalidation if the source object file has been freed. */
37 block_object *prev;
38 block_object *next;
41 struct block_syms_iterator_object {
42 PyObject_HEAD
43 /* The block. */
44 const struct block *block;
45 /* The iterator for that block. */
46 struct block_iterator iter;
47 /* Has the iterator been initialized flag. */
48 int initialized_p;
49 /* Pointer back to the original source block object. Needed to
50 check if the block is still valid, and has not been invalidated
51 when an object file has been freed. */
52 block_object *source;
55 /* Require a valid block. All access to block_object->block should be
56 gated by this call. */
57 #define BLPY_REQUIRE_VALID(block_obj, block) \
58 do { \
59 block = block_object_to_block (block_obj); \
60 if (block == NULL) \
61 { \
62 PyErr_SetString (PyExc_RuntimeError, \
63 _("Block is invalid.")); \
64 return NULL; \
65 } \
66 } while (0)
68 /* Require a valid block. This macro is called during block iterator
69 creation, and at each next call. */
70 #define BLPY_ITER_REQUIRE_VALID(block_obj) \
71 do { \
72 if (block_obj->block == NULL) \
73 { \
74 PyErr_SetString (PyExc_RuntimeError, \
75 _("Source block for iterator is invalid.")); \
76 return NULL; \
77 } \
78 } while (0)
80 /* This is called when an objfile is about to be freed.
81 Invalidate the block as further actions on the block would result
82 in bad data. All access to obj->symbol should be gated by
83 BLPY_REQUIRE_VALID which will raise an exception on invalid
84 blocks. */
85 struct blpy_deleter
87 void operator() (block_object *obj)
89 while (obj)
91 block_object *next = obj->next;
93 obj->block = NULL;
94 obj->objfile = NULL;
95 obj->next = NULL;
96 obj->prev = NULL;
98 obj = next;
103 extern PyTypeObject block_syms_iterator_object_type
104 CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("block_syms_iterator_object");
105 static const registry<objfile>::key<block_object, blpy_deleter>
106 blpy_objfile_data_key;
108 static PyObject *
109 blpy_iter (PyObject *self)
111 block_syms_iterator_object *block_iter_obj;
112 const struct block *block = NULL;
114 BLPY_REQUIRE_VALID (self, block);
116 block_iter_obj = PyObject_New (block_syms_iterator_object,
117 &block_syms_iterator_object_type);
118 if (block_iter_obj == NULL)
119 return NULL;
121 block_iter_obj->block = block;
122 block_iter_obj->initialized_p = 0;
123 Py_INCREF (self);
124 block_iter_obj->source = (block_object *) self;
126 return (PyObject *) block_iter_obj;
129 static PyObject *
130 blpy_get_start (PyObject *self, void *closure)
132 const struct block *block = NULL;
134 BLPY_REQUIRE_VALID (self, block);
136 return gdb_py_object_from_ulongest (block->start ()).release ();
139 static PyObject *
140 blpy_get_end (PyObject *self, void *closure)
142 const struct block *block = NULL;
144 BLPY_REQUIRE_VALID (self, block);
146 return gdb_py_object_from_ulongest (block->end ()).release ();
149 static PyObject *
150 blpy_get_function (PyObject *self, void *closure)
152 struct symbol *sym;
153 const struct block *block;
155 BLPY_REQUIRE_VALID (self, block);
157 sym = block->function ();
158 if (sym)
159 return symbol_to_symbol_object (sym);
161 Py_RETURN_NONE;
164 static PyObject *
165 blpy_get_superblock (PyObject *self, void *closure)
167 const struct block *block;
168 const struct block *super_block;
169 block_object *self_obj = (block_object *) self;
171 BLPY_REQUIRE_VALID (self, block);
173 super_block = block->superblock ();
174 if (super_block)
175 return block_to_block_object (super_block, self_obj->objfile);
177 Py_RETURN_NONE;
180 /* Return the global block associated to this block. */
182 static PyObject *
183 blpy_get_global_block (PyObject *self, void *closure)
185 const struct block *block;
186 const struct block *global_block;
187 block_object *self_obj = (block_object *) self;
189 BLPY_REQUIRE_VALID (self, block);
191 global_block = block->global_block ();
193 return block_to_block_object (global_block,
194 self_obj->objfile);
198 /* Return the static block associated to this block. Return None
199 if we cannot get the static block (this is the global block). */
201 static PyObject *
202 blpy_get_static_block (PyObject *self, void *closure)
204 const struct block *block;
205 const struct block *static_block;
206 block_object *self_obj = (block_object *) self;
208 BLPY_REQUIRE_VALID (self, block);
210 if (block->superblock () == NULL)
211 Py_RETURN_NONE;
213 static_block = block->static_block ();
215 return block_to_block_object (static_block, self_obj->objfile);
218 /* Implementation of gdb.Block.is_global (self) -> Boolean.
219 Returns True if this block object is a global block. */
221 static PyObject *
222 blpy_is_global (PyObject *self, void *closure)
224 const struct block *block;
226 BLPY_REQUIRE_VALID (self, block);
228 if (block->superblock ())
229 Py_RETURN_FALSE;
231 Py_RETURN_TRUE;
234 /* Implementation of gdb.Block.is_static (self) -> Boolean.
235 Returns True if this block object is a static block. */
237 static PyObject *
238 blpy_is_static (PyObject *self, void *closure)
240 const struct block *block;
242 BLPY_REQUIRE_VALID (self, block);
244 if (block->superblock () != NULL
245 && block->superblock ()->superblock () == NULL)
246 Py_RETURN_TRUE;
248 Py_RETURN_FALSE;
251 /* Given a string, returns the gdb.Symbol representing that symbol in this
252 block. If such a symbol does not exist, returns NULL with a Python
253 exception. */
255 static PyObject *
256 blpy_getitem (PyObject *self, PyObject *key)
258 const struct block *block;
260 BLPY_REQUIRE_VALID (self, block);
262 gdb::unique_xmalloc_ptr<char> name = python_string_to_host_string (key);
263 if (name == nullptr)
264 return nullptr;
266 lookup_name_info lookup_name (name.get(), symbol_name_match_type::FULL);
268 /* We use an iterator instead of block_lookup_symbol so that we can
269 look up symbols irrespective of the domain, matching the
270 iterator. It would be confusing if the iterator returns symbols
271 you can't find via getitem. */
272 for (struct symbol *sym : block_iterator_range (block, &lookup_name))
274 /* Just stop at the first match */
275 return symbol_to_symbol_object (sym);
278 PyErr_SetObject (PyExc_KeyError, key);
279 return nullptr;
282 static void
283 blpy_dealloc (PyObject *obj)
285 block_object *block = (block_object *) obj;
287 if (block->prev)
288 block->prev->next = block->next;
289 else if (block->objfile)
290 blpy_objfile_data_key.set (block->objfile, block->next);
291 if (block->next)
292 block->next->prev = block->prev;
293 block->block = NULL;
294 Py_TYPE (obj)->tp_free (obj);
297 /* Given a block, and a block_object that has previously been
298 allocated and initialized, populate the block_object with the
299 struct block data. Also, register the block_object life-cycle
300 with the life-cycle of the object file associated with this
301 block, if needed. */
302 static void
303 set_block (block_object *obj, const struct block *block,
304 struct objfile *objfile)
306 obj->block = block;
307 obj->prev = NULL;
308 if (objfile)
310 obj->objfile = objfile;
311 obj->next = blpy_objfile_data_key.get (objfile);
312 if (obj->next)
313 obj->next->prev = obj;
314 blpy_objfile_data_key.set (objfile, obj);
316 else
317 obj->next = NULL;
320 /* Create a new block object (gdb.Block) that encapsulates the struct
321 block object from GDB. */
322 PyObject *
323 block_to_block_object (const struct block *block, struct objfile *objfile)
325 block_object *block_obj;
327 block_obj = PyObject_New (block_object, &block_object_type);
328 if (block_obj)
329 set_block (block_obj, block, objfile);
331 return (PyObject *) block_obj;
334 /* Return struct block reference that is wrapped by this object. */
335 const struct block *
336 block_object_to_block (PyObject *obj)
338 if (! PyObject_TypeCheck (obj, &block_object_type))
339 return NULL;
340 return ((block_object *) obj)->block;
343 /* Return a reference to the block iterator. */
344 static PyObject *
345 blpy_block_syms_iter (PyObject *self)
347 block_syms_iterator_object *iter_obj = (block_syms_iterator_object *) self;
349 BLPY_ITER_REQUIRE_VALID (iter_obj->source);
351 Py_INCREF (self);
352 return self;
355 /* Return the next symbol in the iteration through the block's
356 dictionary. */
357 static PyObject *
358 blpy_block_syms_iternext (PyObject *self)
360 block_syms_iterator_object *iter_obj = (block_syms_iterator_object *) self;
361 struct symbol *sym;
363 BLPY_ITER_REQUIRE_VALID (iter_obj->source);
365 if (!iter_obj->initialized_p)
367 sym = block_iterator_first (iter_obj->block, &(iter_obj->iter));
368 iter_obj->initialized_p = 1;
370 else
371 sym = block_iterator_next (&(iter_obj->iter));
373 if (sym == NULL)
375 PyErr_SetString (PyExc_StopIteration, _("Symbol is null."));
376 return NULL;
379 return symbol_to_symbol_object (sym);
382 static void
383 blpy_block_syms_dealloc (PyObject *obj)
385 block_syms_iterator_object *iter_obj = (block_syms_iterator_object *) obj;
387 Py_XDECREF (iter_obj->source);
388 Py_TYPE (obj)->tp_free (obj);
391 /* Implementation of gdb.Block.is_valid (self) -> Boolean.
392 Returns True if this block object still exists in GDB. */
394 static PyObject *
395 blpy_is_valid (PyObject *self, PyObject *args)
397 const struct block *block;
399 block = block_object_to_block (self);
400 if (block == NULL)
401 Py_RETURN_FALSE;
403 Py_RETURN_TRUE;
406 /* Implementation of gdb.BlockIterator.is_valid (self) -> Boolean.
407 Returns True if this block iterator object still exists in GDB */
409 static PyObject *
410 blpy_iter_is_valid (PyObject *self, PyObject *args)
412 block_syms_iterator_object *iter_obj =
413 (block_syms_iterator_object *) self;
415 if (iter_obj->source->block == NULL)
416 Py_RETURN_FALSE;
418 Py_RETURN_TRUE;
421 /* __repr__ implementation for gdb.Block. */
423 static PyObject *
424 blpy_repr (PyObject *self)
426 const auto block = block_object_to_block (self);
427 if (block == nullptr)
428 return gdb_py_invalid_object_repr (self);
430 const auto name = block->function () ?
431 block->function ()->print_name () : "<anonymous>";
433 std::string str;
434 unsigned int written_symbols = 0;
435 const int len = mdict_size (block->multidict ());
436 static constexpr int SYMBOLS_TO_SHOW = 5;
437 for (struct symbol *symbol : block_iterator_range (block))
439 if (written_symbols == SYMBOLS_TO_SHOW)
441 const int remaining = len - SYMBOLS_TO_SHOW;
442 if (remaining == 1)
443 str += string_printf ("... (%d more symbol)", remaining);
444 else
445 str += string_printf ("... (%d more symbols)", remaining);
446 break;
448 str += symbol->print_name ();
449 if (++written_symbols < len)
450 str += ", ";
452 return PyUnicode_FromFormat ("<%s %s {%s}>", Py_TYPE (self)->tp_name,
453 name, str.c_str ());
456 static int CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION
457 gdbpy_initialize_blocks (void)
459 block_object_type.tp_new = PyType_GenericNew;
460 if (PyType_Ready (&block_object_type) < 0)
461 return -1;
463 block_syms_iterator_object_type.tp_new = PyType_GenericNew;
464 if (PyType_Ready (&block_syms_iterator_object_type) < 0)
465 return -1;
467 if (gdb_pymodule_addobject (gdb_module, "Block",
468 (PyObject *) &block_object_type) < 0)
469 return -1;
471 return gdb_pymodule_addobject (gdb_module, "BlockIterator",
472 (PyObject *) &block_syms_iterator_object_type);
475 GDBPY_INITIALIZE_FILE (gdbpy_initialize_blocks);
479 static PyMethodDef block_object_methods[] = {
480 { "is_valid", blpy_is_valid, METH_NOARGS,
481 "is_valid () -> Boolean.\n\
482 Return true if this block is valid, false if not." },
483 {NULL} /* Sentinel */
486 static gdb_PyGetSetDef block_object_getset[] = {
487 { "start", blpy_get_start, NULL, "Start address of the block.", NULL },
488 { "end", blpy_get_end, NULL, "End address of the block.", NULL },
489 { "function", blpy_get_function, NULL,
490 "Symbol that names the block, or None.", NULL },
491 { "superblock", blpy_get_superblock, NULL,
492 "Block containing the block, or None.", NULL },
493 { "global_block", blpy_get_global_block, NULL,
494 "Block containing the global block.", NULL },
495 { "static_block", blpy_get_static_block, NULL,
496 "Block containing the static block.", NULL },
497 { "is_static", blpy_is_static, NULL,
498 "Whether this block is a static block.", NULL },
499 { "is_global", blpy_is_global, NULL,
500 "Whether this block is a global block.", NULL },
501 { NULL } /* Sentinel */
504 static PyMappingMethods block_object_as_mapping = {
505 NULL,
506 blpy_getitem,
507 NULL
510 PyTypeObject block_object_type = {
511 PyVarObject_HEAD_INIT (NULL, 0)
512 "gdb.Block", /*tp_name*/
513 sizeof (block_object), /*tp_basicsize*/
514 0, /*tp_itemsize*/
515 blpy_dealloc, /*tp_dealloc*/
516 0, /*tp_print*/
517 0, /*tp_getattr*/
518 0, /*tp_setattr*/
519 0, /*tp_compare*/
520 blpy_repr, /*tp_repr*/
521 0, /*tp_as_number*/
522 0, /*tp_as_sequence*/
523 &block_object_as_mapping, /*tp_as_mapping*/
524 0, /*tp_hash */
525 0, /*tp_call*/
526 0, /*tp_str*/
527 0, /*tp_getattro*/
528 0, /*tp_setattro*/
529 0, /*tp_as_buffer*/
530 Py_TPFLAGS_DEFAULT, /*tp_flags*/
531 "GDB block object", /* tp_doc */
532 0, /* tp_traverse */
533 0, /* tp_clear */
534 0, /* tp_richcompare */
535 0, /* tp_weaklistoffset */
536 blpy_iter, /* tp_iter */
537 0, /* tp_iternext */
538 block_object_methods, /* tp_methods */
539 0, /* tp_members */
540 block_object_getset /* tp_getset */
543 static PyMethodDef block_iterator_object_methods[] = {
544 { "is_valid", blpy_iter_is_valid, METH_NOARGS,
545 "is_valid () -> Boolean.\n\
546 Return true if this block iterator is valid, false if not." },
547 {NULL} /* Sentinel */
550 PyTypeObject block_syms_iterator_object_type = {
551 PyVarObject_HEAD_INIT (NULL, 0)
552 "gdb.BlockIterator", /*tp_name*/
553 sizeof (block_syms_iterator_object), /*tp_basicsize*/
554 0, /*tp_itemsize*/
555 blpy_block_syms_dealloc, /*tp_dealloc*/
556 0, /*tp_print*/
557 0, /*tp_getattr*/
558 0, /*tp_setattr*/
559 0, /*tp_compare*/
560 0, /*tp_repr*/
561 0, /*tp_as_number*/
562 0, /*tp_as_sequence*/
563 0, /*tp_as_mapping*/
564 0, /*tp_hash */
565 0, /*tp_call*/
566 0, /*tp_str*/
567 0, /*tp_getattro*/
568 0, /*tp_setattro*/
569 0, /*tp_as_buffer*/
570 Py_TPFLAGS_DEFAULT, /*tp_flags*/
571 "GDB block syms iterator object", /*tp_doc */
572 0, /*tp_traverse */
573 0, /*tp_clear */
574 0, /*tp_richcompare */
575 0, /*tp_weaklistoffset */
576 blpy_block_syms_iter, /*tp_iter */
577 blpy_block_syms_iternext, /*tp_iternext */
578 block_iterator_object_methods /*tp_methods */