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/>. */
21 #include "dictionary.h"
23 #include "python-internal.h"
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
{
39 const struct block
*block
;
40 /* The iterator for that block. */
41 struct block_iterator iter
;
42 /* Has the iterator been initialized flag. */
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. */
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) \
54 block = block_object_to_block (block_obj); \
57 PyErr_SetString (PyExc_RuntimeError, \
58 _("Block is invalid.")); \
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) \
67 if (block_obj->block == NULL) \
69 PyErr_SetString (PyExc_RuntimeError, \
70 _("Source block for iterator is invalid.")); \
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
;
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
)
93 block_iter_obj
->block
= block
;
94 block_iter_obj
->initialized_p
= 0;
96 block_iter_obj
->source
= (block_object
*) self
;
98 return (PyObject
*) block_iter_obj
;
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 ();
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 ();
122 blpy_get_function (PyObject
*self
, void *closure
)
125 const struct block
*block
;
127 BLPY_REQUIRE_VALID (self
, block
);
129 sym
= block
->function ();
131 return symbol_to_symbol_object (sym
);
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 ();
147 return block_to_block_object (super_block
, self_obj
->objfile
);
152 /* Return the global block associated to this block. */
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
,
170 /* Return the static block associated to this block. Return None
171 if we cannot get the static block (this is the global block). */
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
)
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. */
194 blpy_is_global (PyObject
*self
, void *closure
)
196 const struct block
*block
;
198 BLPY_REQUIRE_VALID (self
, block
);
200 if (block
->superblock ())
206 /* Implementation of gdb.Block.is_static (self) -> Boolean.
207 Returns True if this block object is a static block. */
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
)
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
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
);
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
);
254 /* Deleter function for the hash table. */
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. */
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. */
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
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
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. */
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
,
320 if (result
!= nullptr)
322 PyObject
*py_result
= (PyObject
*) result
;
323 Py_INCREF (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
);
334 return (PyObject
*) result
;
337 /* Return struct block reference that is wrapped by this object. */
339 block_object_to_block (PyObject
*obj
)
341 if (! PyObject_TypeCheck (obj
, &block_object_type
))
343 return ((block_object
*) obj
)->block
;
346 /* Return a reference to the block iterator. */
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
);
358 /* Return the next symbol in the iteration through the block's
361 blpy_block_syms_iternext (PyObject
*self
)
363 block_syms_iterator_object
*iter_obj
= (block_syms_iterator_object
*) self
;
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;
374 sym
= block_iterator_next (&(iter_obj
->iter
));
378 PyErr_SetString (PyExc_StopIteration
, _("Symbol is null."));
382 return symbol_to_symbol_object (sym
);
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. */
398 blpy_is_valid (PyObject
*self
, PyObject
*args
)
400 const struct block
*block
;
402 block
= block_object_to_block (self
);
409 /* Implementation of gdb.BlockIterator.is_valid (self) -> Boolean.
410 Returns True if this block iterator object still exists in GDB */
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
)
424 /* __repr__ implementation for gdb.Block. */
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>";
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
;
446 str
+= string_printf ("... (%d more symbol)", remaining
);
448 str
+= string_printf ("... (%d more symbols)", remaining
);
451 str
+= symbol
->print_name ();
452 if (++written_symbols
< len
)
455 return PyUnicode_FromFormat ("<%s %s {%s}>", Py_TYPE (self
)->tp_name
,
459 /* Hash function for block objects. */
462 blpy_hash (PyObject
*self
)
464 /* Python doesn't really expose its pointer hash function, so we use
466 Py_hash_t result
= (Py_hash_t
) htab_hash_pointer (self
);
467 /* -1 has a special meaning for Python. */
473 /* Implements the equality comparison for Block objects. All other
474 comparison operators will throw NotImplemented, as they aren't
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 (gdbpy_type_ready (&block_object_type
) < 0)
499 block_syms_iterator_object_type
.tp_new
= PyType_GenericNew
;
500 if (gdbpy_type_ready (&block_syms_iterator_object_type
) < 0)
506 GDBPY_INITIALIZE_FILE (gdbpy_initialize_blocks
);
510 static PyMethodDef block_object_methods
[] = {
511 { "is_valid", blpy_is_valid
, METH_NOARGS
,
512 "is_valid () -> Boolean.\n\
513 Return true if this block is valid, false if not." },
514 {NULL
} /* Sentinel */
517 static gdb_PyGetSetDef block_object_getset
[] = {
518 { "start", blpy_get_start
, NULL
, "Start address of the block.", NULL
},
519 { "end", blpy_get_end
, NULL
, "End address of the block.", NULL
},
520 { "function", blpy_get_function
, NULL
,
521 "Symbol that names the block, or None.", NULL
},
522 { "superblock", blpy_get_superblock
, NULL
,
523 "Block containing the block, or None.", NULL
},
524 { "global_block", blpy_get_global_block
, NULL
,
525 "Block containing the global block.", NULL
},
526 { "static_block", blpy_get_static_block
, NULL
,
527 "Block containing the static block.", NULL
},
528 { "is_static", blpy_is_static
, NULL
,
529 "Whether this block is a static block.", NULL
},
530 { "is_global", blpy_is_global
, NULL
,
531 "Whether this block is a global block.", NULL
},
532 { NULL
} /* Sentinel */
535 static PyMappingMethods block_object_as_mapping
= {
541 PyTypeObject block_object_type
= {
542 PyVarObject_HEAD_INIT (NULL
, 0)
543 "gdb.Block", /*tp_name*/
544 sizeof (block_object
), /*tp_basicsize*/
546 blpy_dealloc
, /*tp_dealloc*/
551 blpy_repr
, /*tp_repr*/
553 0, /*tp_as_sequence*/
554 &block_object_as_mapping
, /*tp_as_mapping*/
555 blpy_hash
, /*tp_hash */
561 Py_TPFLAGS_DEFAULT
, /*tp_flags*/
562 "GDB block object", /* tp_doc */
565 blpy_richcompare
, /* tp_richcompare */
566 0, /* tp_weaklistoffset */
567 blpy_iter
, /* tp_iter */
569 block_object_methods
, /* tp_methods */
571 block_object_getset
/* tp_getset */
574 static PyMethodDef block_iterator_object_methods
[] = {
575 { "is_valid", blpy_iter_is_valid
, METH_NOARGS
,
576 "is_valid () -> Boolean.\n\
577 Return true if this block iterator is valid, false if not." },
578 {NULL
} /* Sentinel */
581 PyTypeObject block_syms_iterator_object_type
= {
582 PyVarObject_HEAD_INIT (NULL
, 0)
583 "gdb.BlockIterator", /*tp_name*/
584 sizeof (block_syms_iterator_object
), /*tp_basicsize*/
586 blpy_block_syms_dealloc
, /*tp_dealloc*/
593 0, /*tp_as_sequence*/
601 Py_TPFLAGS_DEFAULT
, /*tp_flags*/
602 "GDB block syms iterator object", /*tp_doc */
605 0, /*tp_richcompare */
606 0, /*tp_weaklistoffset */
607 blpy_block_syms_iter
, /*tp_iter */
608 blpy_block_syms_iternext
, /*tp_iternext */
609 block_iterator_object_methods
/*tp_methods */