Automatic date update in version.in
[binutils-gdb.git] / gdb / python / py-block.c
blob62e93d55072d27b3746aade1b3def55fc71a32de
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 "block.h"
21 #include "dictionary.h"
22 #include "symtab.h"
23 #include "python-internal.h"
24 #include "objfiles.h"
26 struct block_object {
27 PyObject_HEAD
28 /* The GDB block structure that represents a frame's code block. */
29 const struct block *block;
30 /* The backing object file. There is no direct relationship in GDB
31 between a block and an object file. When a block is created also
32 store a pointer to the object file for later use. */
33 struct objfile *objfile;
36 struct block_syms_iterator_object {
37 PyObject_HEAD
38 /* The block. */
39 const struct block *block;
40 /* The iterator for that block. */
41 struct block_iterator iter;
42 /* Has the iterator been initialized flag. */
43 int initialized_p;
44 /* Pointer back to the original source block object. Needed to
45 check if the block is still valid, and has not been invalidated
46 when an object file has been freed. */
47 block_object *source;
50 /* Require a valid block. All access to block_object->block should be
51 gated by this call. */
52 #define BLPY_REQUIRE_VALID(block_obj, block) \
53 do { \
54 block = block_object_to_block (block_obj); \
55 if (block == NULL) \
56 { \
57 PyErr_SetString (PyExc_RuntimeError, \
58 _("Block is invalid.")); \
59 return NULL; \
60 } \
61 } while (0)
63 /* Require a valid block. This macro is called during block iterator
64 creation, and at each next call. */
65 #define BLPY_ITER_REQUIRE_VALID(block_obj) \
66 do { \
67 if (block_obj->block == NULL) \
68 { \
69 PyErr_SetString (PyExc_RuntimeError, \
70 _("Source block for iterator is invalid.")); \
71 return NULL; \
72 } \
73 } while (0)
75 extern PyTypeObject block_syms_iterator_object_type
76 CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("block_syms_iterator_object");
77 static const registry<objfile>::key<htab, htab_deleter>
78 blpy_objfile_data_key;
80 static PyObject *
81 blpy_iter (PyObject *self)
83 block_syms_iterator_object *block_iter_obj;
84 const struct block *block = NULL;
86 BLPY_REQUIRE_VALID (self, block);
88 block_iter_obj = PyObject_New (block_syms_iterator_object,
89 &block_syms_iterator_object_type);
90 if (block_iter_obj == NULL)
91 return NULL;
93 block_iter_obj->block = block;
94 block_iter_obj->initialized_p = 0;
95 Py_INCREF (self);
96 block_iter_obj->source = (block_object *) self;
98 return (PyObject *) block_iter_obj;
101 static PyObject *
102 blpy_get_start (PyObject *self, void *closure)
104 const struct block *block = NULL;
106 BLPY_REQUIRE_VALID (self, block);
108 return gdb_py_object_from_ulongest (block->start ()).release ();
111 static PyObject *
112 blpy_get_end (PyObject *self, void *closure)
114 const struct block *block = NULL;
116 BLPY_REQUIRE_VALID (self, block);
118 return gdb_py_object_from_ulongest (block->end ()).release ();
121 static PyObject *
122 blpy_get_function (PyObject *self, void *closure)
124 struct symbol *sym;
125 const struct block *block;
127 BLPY_REQUIRE_VALID (self, block);
129 sym = block->function ();
130 if (sym)
131 return symbol_to_symbol_object (sym);
133 Py_RETURN_NONE;
136 static PyObject *
137 blpy_get_superblock (PyObject *self, void *closure)
139 const struct block *block;
140 const struct block *super_block;
141 block_object *self_obj = (block_object *) self;
143 BLPY_REQUIRE_VALID (self, block);
145 super_block = block->superblock ();
146 if (super_block)
147 return block_to_block_object (super_block, self_obj->objfile);
149 Py_RETURN_NONE;
152 /* Return the global block associated to this block. */
154 static PyObject *
155 blpy_get_global_block (PyObject *self, void *closure)
157 const struct block *block;
158 const struct block *global_block;
159 block_object *self_obj = (block_object *) self;
161 BLPY_REQUIRE_VALID (self, block);
163 global_block = block->global_block ();
165 return block_to_block_object (global_block,
166 self_obj->objfile);
170 /* Return the static block associated to this block. Return None
171 if we cannot get the static block (this is the global block). */
173 static PyObject *
174 blpy_get_static_block (PyObject *self, void *closure)
176 const struct block *block;
177 const struct block *static_block;
178 block_object *self_obj = (block_object *) self;
180 BLPY_REQUIRE_VALID (self, block);
182 if (block->superblock () == NULL)
183 Py_RETURN_NONE;
185 static_block = block->static_block ();
187 return block_to_block_object (static_block, self_obj->objfile);
190 /* Implementation of gdb.Block.is_global (self) -> Boolean.
191 Returns True if this block object is a global block. */
193 static PyObject *
194 blpy_is_global (PyObject *self, void *closure)
196 const struct block *block;
198 BLPY_REQUIRE_VALID (self, block);
200 if (block->superblock ())
201 Py_RETURN_FALSE;
203 Py_RETURN_TRUE;
206 /* Implementation of gdb.Block.is_static (self) -> Boolean.
207 Returns True if this block object is a static block. */
209 static PyObject *
210 blpy_is_static (PyObject *self, void *closure)
212 const struct block *block;
214 BLPY_REQUIRE_VALID (self, block);
216 if (block->superblock () != NULL
217 && block->superblock ()->superblock () == NULL)
218 Py_RETURN_TRUE;
220 Py_RETURN_FALSE;
223 /* Given a string, returns the gdb.Symbol representing that symbol in this
224 block. If such a symbol does not exist, returns NULL with a Python
225 exception. */
227 static PyObject *
228 blpy_getitem (PyObject *self, PyObject *key)
230 const struct block *block;
232 BLPY_REQUIRE_VALID (self, block);
234 gdb::unique_xmalloc_ptr<char> name = python_string_to_host_string (key);
235 if (name == nullptr)
236 return nullptr;
238 lookup_name_info lookup_name (name.get(), symbol_name_match_type::FULL);
240 /* We use an iterator instead of block_lookup_symbol so that we can
241 look up symbols irrespective of the domain, matching the
242 iterator. It would be confusing if the iterator returns symbols
243 you can't find via getitem. */
244 for (struct symbol *sym : block_iterator_range (block, &lookup_name))
246 /* Just stop at the first match */
247 return symbol_to_symbol_object (sym);
250 PyErr_SetObject (PyExc_KeyError, key);
251 return nullptr;
254 /* Deleter function for the hash table. */
256 static void
257 block_object_del (void *obj)
259 block_object *block = (block_object *) obj;
260 block->block = nullptr;
261 block->objfile = nullptr;
264 /* Hash function for the hash table. */
266 static hashval_t
267 block_object_hash (const void *obj)
269 const block_object *block = (const block_object *) obj;
270 return htab_hash_pointer (block->block);
273 /* Equality function for the hash table. Note that searches must be
274 done with a plain block. */
276 static int
277 block_object_eq (const void *a, const void *b)
279 const block_object *blocka = (const block_object *) a;
280 const block *blockb = (const block *) b;
281 return blocka->block == blockb;
284 /* Called when a gdb.Block is destroyed. This removes it from the
285 hash. */
287 static void
288 blpy_dealloc (PyObject *obj)
290 block_object *block = (block_object *) obj;
292 if (block->objfile != nullptr)
294 htab_t table = blpy_objfile_data_key.get (block->objfile);
295 hashval_t hash = block_object_hash (block);
296 /* This will clear the contents of the block as a side
297 effect. */
298 htab_remove_elt_with_hash (table, block->block, hash);
301 Py_TYPE (obj)->tp_free (obj);
304 /* Create a new block object (gdb.Block) that encapsulates the struct
305 block object from GDB. */
306 PyObject *
307 block_to_block_object (const struct block *block, struct objfile *objfile)
309 htab_t table = blpy_objfile_data_key.get (objfile);
310 if (table == nullptr)
312 table = htab_create_alloc (10, block_object_hash, block_object_eq,
313 block_object_del, xcalloc, xfree);
314 blpy_objfile_data_key.set (objfile, table);
317 hashval_t hash = htab_hash_pointer (block);
318 block_object *result = (block_object *) htab_find_with_hash (table, block,
319 hash);
320 if (result != nullptr)
322 PyObject *py_result = (PyObject *) result;
323 Py_INCREF (py_result);
324 return py_result;
327 result = PyObject_New (block_object, &block_object_type);
328 result->block = block;
329 result->objfile = objfile;
331 void **slot = htab_find_slot_with_hash (table, block, hash, INSERT);
332 *slot = result;
334 return (PyObject *) result;
337 /* Return struct block reference that is wrapped by this object. */
338 const struct block *
339 block_object_to_block (PyObject *obj)
341 if (! PyObject_TypeCheck (obj, &block_object_type))
342 return NULL;
343 return ((block_object *) obj)->block;
346 /* Return a reference to the block iterator. */
347 static PyObject *
348 blpy_block_syms_iter (PyObject *self)
350 block_syms_iterator_object *iter_obj = (block_syms_iterator_object *) self;
352 BLPY_ITER_REQUIRE_VALID (iter_obj->source);
354 Py_INCREF (self);
355 return self;
358 /* Return the next symbol in the iteration through the block's
359 dictionary. */
360 static PyObject *
361 blpy_block_syms_iternext (PyObject *self)
363 block_syms_iterator_object *iter_obj = (block_syms_iterator_object *) self;
364 struct symbol *sym;
366 BLPY_ITER_REQUIRE_VALID (iter_obj->source);
368 if (!iter_obj->initialized_p)
370 sym = block_iterator_first (iter_obj->block, &(iter_obj->iter));
371 iter_obj->initialized_p = 1;
373 else
374 sym = block_iterator_next (&(iter_obj->iter));
376 if (sym == NULL)
378 PyErr_SetString (PyExc_StopIteration, _("Symbol is null."));
379 return NULL;
382 return symbol_to_symbol_object (sym);
385 static void
386 blpy_block_syms_dealloc (PyObject *obj)
388 block_syms_iterator_object *iter_obj = (block_syms_iterator_object *) obj;
390 Py_XDECREF (iter_obj->source);
391 Py_TYPE (obj)->tp_free (obj);
394 /* Implementation of gdb.Block.is_valid (self) -> Boolean.
395 Returns True if this block object still exists in GDB. */
397 static PyObject *
398 blpy_is_valid (PyObject *self, PyObject *args)
400 const struct block *block;
402 block = block_object_to_block (self);
403 if (block == NULL)
404 Py_RETURN_FALSE;
406 Py_RETURN_TRUE;
409 /* Implementation of gdb.BlockIterator.is_valid (self) -> Boolean.
410 Returns True if this block iterator object still exists in GDB */
412 static PyObject *
413 blpy_iter_is_valid (PyObject *self, PyObject *args)
415 block_syms_iterator_object *iter_obj =
416 (block_syms_iterator_object *) self;
418 if (iter_obj->source->block == NULL)
419 Py_RETURN_FALSE;
421 Py_RETURN_TRUE;
424 /* __repr__ implementation for gdb.Block. */
426 static PyObject *
427 blpy_repr (PyObject *self)
429 const auto block = block_object_to_block (self);
430 if (block == nullptr)
431 return gdb_py_invalid_object_repr (self);
433 const auto name = block->function () ?
434 block->function ()->print_name () : "<anonymous>";
436 std::string str;
437 unsigned int written_symbols = 0;
438 const int len = mdict_size (block->multidict ());
439 static constexpr int SYMBOLS_TO_SHOW = 5;
440 for (struct symbol *symbol : block_iterator_range (block))
442 if (written_symbols == SYMBOLS_TO_SHOW)
444 const int remaining = len - SYMBOLS_TO_SHOW;
445 if (remaining == 1)
446 str += string_printf ("... (%d more symbol)", remaining);
447 else
448 str += string_printf ("... (%d more symbols)", remaining);
449 break;
451 str += symbol->print_name ();
452 if (++written_symbols < len)
453 str += ", ";
455 return PyUnicode_FromFormat ("<%s %s {%s}>", Py_TYPE (self)->tp_name,
456 name, str.c_str ());
459 /* Hash function for block objects. */
461 static Py_hash_t
462 blpy_hash (PyObject *self)
464 /* Python doesn't really expose its pointer hash function, so we use
465 our own. */
466 Py_hash_t result = (Py_hash_t) htab_hash_pointer (self);
467 /* -1 has a special meaning for Python. */
468 if (result == -1)
469 result = -2;
470 return result;
473 /* Implements the equality comparison for Block objects. All other
474 comparison operators will throw NotImplemented, as they aren't
475 valid for blocks. */
477 static PyObject *
478 blpy_richcompare (PyObject *self, PyObject *other, int op)
480 if (!PyObject_TypeCheck (other, &block_object_type)
481 || (op != Py_EQ && op != Py_NE))
483 Py_INCREF (Py_NotImplemented);
484 return Py_NotImplemented;
487 bool expected = self == other;
488 bool equal = op == Py_EQ;
489 return PyBool_FromLong (equal == expected);
492 static int CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION
493 gdbpy_initialize_blocks (void)
495 block_object_type.tp_new = PyType_GenericNew;
496 if (PyType_Ready (&block_object_type) < 0)
497 return -1;
499 block_syms_iterator_object_type.tp_new = PyType_GenericNew;
500 if (PyType_Ready (&block_syms_iterator_object_type) < 0)
501 return -1;
503 if (gdb_pymodule_addobject (gdb_module, "Block",
504 (PyObject *) &block_object_type) < 0)
505 return -1;
507 return gdb_pymodule_addobject (gdb_module, "BlockIterator",
508 (PyObject *) &block_syms_iterator_object_type);
511 GDBPY_INITIALIZE_FILE (gdbpy_initialize_blocks);
515 static PyMethodDef block_object_methods[] = {
516 { "is_valid", blpy_is_valid, METH_NOARGS,
517 "is_valid () -> Boolean.\n\
518 Return true if this block is valid, false if not." },
519 {NULL} /* Sentinel */
522 static gdb_PyGetSetDef block_object_getset[] = {
523 { "start", blpy_get_start, NULL, "Start address of the block.", NULL },
524 { "end", blpy_get_end, NULL, "End address of the block.", NULL },
525 { "function", blpy_get_function, NULL,
526 "Symbol that names the block, or None.", NULL },
527 { "superblock", blpy_get_superblock, NULL,
528 "Block containing the block, or None.", NULL },
529 { "global_block", blpy_get_global_block, NULL,
530 "Block containing the global block.", NULL },
531 { "static_block", blpy_get_static_block, NULL,
532 "Block containing the static block.", NULL },
533 { "is_static", blpy_is_static, NULL,
534 "Whether this block is a static block.", NULL },
535 { "is_global", blpy_is_global, NULL,
536 "Whether this block is a global block.", NULL },
537 { NULL } /* Sentinel */
540 static PyMappingMethods block_object_as_mapping = {
541 NULL,
542 blpy_getitem,
543 NULL
546 PyTypeObject block_object_type = {
547 PyVarObject_HEAD_INIT (NULL, 0)
548 "gdb.Block", /*tp_name*/
549 sizeof (block_object), /*tp_basicsize*/
550 0, /*tp_itemsize*/
551 blpy_dealloc, /*tp_dealloc*/
552 0, /*tp_print*/
553 0, /*tp_getattr*/
554 0, /*tp_setattr*/
555 0, /*tp_compare*/
556 blpy_repr, /*tp_repr*/
557 0, /*tp_as_number*/
558 0, /*tp_as_sequence*/
559 &block_object_as_mapping, /*tp_as_mapping*/
560 blpy_hash, /*tp_hash */
561 0, /*tp_call*/
562 0, /*tp_str*/
563 0, /*tp_getattro*/
564 0, /*tp_setattro*/
565 0, /*tp_as_buffer*/
566 Py_TPFLAGS_DEFAULT, /*tp_flags*/
567 "GDB block object", /* tp_doc */
568 0, /* tp_traverse */
569 0, /* tp_clear */
570 blpy_richcompare, /* tp_richcompare */
571 0, /* tp_weaklistoffset */
572 blpy_iter, /* tp_iter */
573 0, /* tp_iternext */
574 block_object_methods, /* tp_methods */
575 0, /* tp_members */
576 block_object_getset /* tp_getset */
579 static PyMethodDef block_iterator_object_methods[] = {
580 { "is_valid", blpy_iter_is_valid, METH_NOARGS,
581 "is_valid () -> Boolean.\n\
582 Return true if this block iterator is valid, false if not." },
583 {NULL} /* Sentinel */
586 PyTypeObject block_syms_iterator_object_type = {
587 PyVarObject_HEAD_INIT (NULL, 0)
588 "gdb.BlockIterator", /*tp_name*/
589 sizeof (block_syms_iterator_object), /*tp_basicsize*/
590 0, /*tp_itemsize*/
591 blpy_block_syms_dealloc, /*tp_dealloc*/
592 0, /*tp_print*/
593 0, /*tp_getattr*/
594 0, /*tp_setattr*/
595 0, /*tp_compare*/
596 0, /*tp_repr*/
597 0, /*tp_as_number*/
598 0, /*tp_as_sequence*/
599 0, /*tp_as_mapping*/
600 0, /*tp_hash */
601 0, /*tp_call*/
602 0, /*tp_str*/
603 0, /*tp_getattro*/
604 0, /*tp_setattro*/
605 0, /*tp_as_buffer*/
606 Py_TPFLAGS_DEFAULT, /*tp_flags*/
607 "GDB block syms iterator object", /*tp_doc */
608 0, /*tp_traverse */
609 0, /*tp_clear */
610 0, /*tp_richcompare */
611 0, /*tp_weaklistoffset */
612 blpy_block_syms_iter, /*tp_iter */
613 blpy_block_syms_iternext, /*tp_iternext */
614 block_iterator_object_methods /*tp_methods */