1 /* Python interface to blocks.
3 Copyright (C) 2008-2021 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/>. */
22 #include "dictionary.h"
24 #include "python-internal.h"
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. */
41 struct block_syms_iterator_object
{
44 const struct block
*block
;
45 /* The iterator for that block. */
46 struct block_iterator iter
;
47 /* Has the iterator been initialized flag. */
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. */
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) \
59 block = block_object_to_block (block_obj); \
62 PyErr_SetString (PyExc_RuntimeError, \
63 _("Block is invalid.")); \
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) \
72 if (block_obj->block == NULL) \
74 PyErr_SetString (PyExc_RuntimeError, \
75 _("Source block for iterator is invalid.")); \
80 extern PyTypeObject block_syms_iterator_object_type
81 CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("block_syms_iterator_object");
82 static const struct objfile_data
*blpy_objfile_data_key
;
85 blpy_iter (PyObject
*self
)
87 block_syms_iterator_object
*block_iter_obj
;
88 const struct block
*block
= NULL
;
90 BLPY_REQUIRE_VALID (self
, block
);
92 block_iter_obj
= PyObject_New (block_syms_iterator_object
,
93 &block_syms_iterator_object_type
);
94 if (block_iter_obj
== NULL
)
97 block_iter_obj
->block
= block
;
98 block_iter_obj
->initialized_p
= 0;
100 block_iter_obj
->source
= (block_object
*) self
;
102 return (PyObject
*) block_iter_obj
;
106 blpy_get_start (PyObject
*self
, void *closure
)
108 const struct block
*block
= NULL
;
110 BLPY_REQUIRE_VALID (self
, block
);
112 return gdb_py_object_from_ulongest (BLOCK_START (block
)).release ();
116 blpy_get_end (PyObject
*self
, void *closure
)
118 const struct block
*block
= NULL
;
120 BLPY_REQUIRE_VALID (self
, block
);
122 return gdb_py_object_from_ulongest (BLOCK_END (block
)).release ();
126 blpy_get_function (PyObject
*self
, void *closure
)
129 const struct block
*block
;
131 BLPY_REQUIRE_VALID (self
, block
);
133 sym
= BLOCK_FUNCTION (block
);
135 return symbol_to_symbol_object (sym
);
141 blpy_get_superblock (PyObject
*self
, void *closure
)
143 const struct block
*block
;
144 const struct block
*super_block
;
145 block_object
*self_obj
= (block_object
*) self
;
147 BLPY_REQUIRE_VALID (self
, block
);
149 super_block
= BLOCK_SUPERBLOCK (block
);
151 return block_to_block_object (super_block
, self_obj
->objfile
);
156 /* Return the global block associated to this block. */
159 blpy_get_global_block (PyObject
*self
, void *closure
)
161 const struct block
*block
;
162 const struct block
*global_block
;
163 block_object
*self_obj
= (block_object
*) self
;
165 BLPY_REQUIRE_VALID (self
, block
);
167 global_block
= block_global_block (block
);
169 return block_to_block_object (global_block
,
174 /* Return the static block associated to this block. Return None
175 if we cannot get the static block (this is the global block). */
178 blpy_get_static_block (PyObject
*self
, void *closure
)
180 const struct block
*block
;
181 const struct block
*static_block
;
182 block_object
*self_obj
= (block_object
*) self
;
184 BLPY_REQUIRE_VALID (self
, block
);
186 if (BLOCK_SUPERBLOCK (block
) == NULL
)
189 static_block
= block_static_block (block
);
191 return block_to_block_object (static_block
, self_obj
->objfile
);
194 /* Implementation of gdb.Block.is_global (self) -> Boolean.
195 Returns True if this block object is a global block. */
198 blpy_is_global (PyObject
*self
, void *closure
)
200 const struct block
*block
;
202 BLPY_REQUIRE_VALID (self
, block
);
204 if (BLOCK_SUPERBLOCK (block
))
210 /* Implementation of gdb.Block.is_static (self) -> Boolean.
211 Returns True if this block object is a static block. */
214 blpy_is_static (PyObject
*self
, void *closure
)
216 const struct block
*block
;
218 BLPY_REQUIRE_VALID (self
, block
);
220 if (BLOCK_SUPERBLOCK (block
) != NULL
221 && BLOCK_SUPERBLOCK (BLOCK_SUPERBLOCK (block
)) == NULL
)
227 /* Given a string, returns the gdb.Symbol representing that symbol in this
228 block. If such a symbol does not exist, returns NULL with a Python
232 blpy_getitem (PyObject
*self
, PyObject
*key
)
234 const struct block
*block
;
236 BLPY_REQUIRE_VALID (self
, block
);
238 gdb::unique_xmalloc_ptr
<char> name
= python_string_to_host_string (key
);
242 lookup_name_info
lookup_name (name
.get(), symbol_name_match_type::FULL
);
244 /* We use ALL_BLOCK_SYMBOLS_WITH_NAME instead of block_lookup_symbol so
245 that we can look up symbols irrespective of the domain, matching the
246 iterator. It would be confusing if the iterator returns symbols you
247 can't find via getitem. */
248 struct block_iterator iter
;
249 struct symbol
*sym
= nullptr;
250 ALL_BLOCK_SYMBOLS_WITH_NAME (block
, lookup_name
, iter
, sym
)
252 /* Just stop at the first match */
258 PyErr_SetObject (PyExc_KeyError
, key
);
261 return symbol_to_symbol_object (sym
);
265 blpy_dealloc (PyObject
*obj
)
267 block_object
*block
= (block_object
*) obj
;
270 block
->prev
->next
= block
->next
;
271 else if (block
->objfile
)
273 set_objfile_data (block
->objfile
, blpy_objfile_data_key
,
277 block
->next
->prev
= block
->prev
;
279 Py_TYPE (obj
)->tp_free (obj
);
282 /* Given a block, and a block_object that has previously been
283 allocated and initialized, populate the block_object with the
284 struct block data. Also, register the block_object life-cycle
285 with the life-cycle of the object file associated with this
288 set_block (block_object
*obj
, const struct block
*block
,
289 struct objfile
*objfile
)
295 obj
->objfile
= objfile
;
296 obj
->next
= ((block_object
*)
297 objfile_data (objfile
, blpy_objfile_data_key
));
299 obj
->next
->prev
= obj
;
300 set_objfile_data (objfile
, blpy_objfile_data_key
, obj
);
306 /* Create a new block object (gdb.Block) that encapsulates the struct
307 block object from GDB. */
309 block_to_block_object (const struct block
*block
, struct objfile
*objfile
)
311 block_object
*block_obj
;
313 block_obj
= PyObject_New (block_object
, &block_object_type
);
315 set_block (block_obj
, block
, objfile
);
317 return (PyObject
*) block_obj
;
320 /* Return struct block reference that is wrapped by this object. */
322 block_object_to_block (PyObject
*obj
)
324 if (! PyObject_TypeCheck (obj
, &block_object_type
))
326 return ((block_object
*) obj
)->block
;
329 /* Return a reference to the block iterator. */
331 blpy_block_syms_iter (PyObject
*self
)
333 block_syms_iterator_object
*iter_obj
= (block_syms_iterator_object
*) self
;
335 BLPY_ITER_REQUIRE_VALID (iter_obj
->source
);
341 /* Return the next symbol in the iteration through the block's
344 blpy_block_syms_iternext (PyObject
*self
)
346 block_syms_iterator_object
*iter_obj
= (block_syms_iterator_object
*) self
;
349 BLPY_ITER_REQUIRE_VALID (iter_obj
->source
);
351 if (!iter_obj
->initialized_p
)
353 sym
= block_iterator_first (iter_obj
->block
, &(iter_obj
->iter
));
354 iter_obj
->initialized_p
= 1;
357 sym
= block_iterator_next (&(iter_obj
->iter
));
361 PyErr_SetString (PyExc_StopIteration
, _("Symbol is null."));
365 return symbol_to_symbol_object (sym
);
369 blpy_block_syms_dealloc (PyObject
*obj
)
371 block_syms_iterator_object
*iter_obj
= (block_syms_iterator_object
*) obj
;
373 Py_XDECREF (iter_obj
->source
);
374 Py_TYPE (obj
)->tp_free (obj
);
377 /* Implementation of gdb.Block.is_valid (self) -> Boolean.
378 Returns True if this block object still exists in GDB. */
381 blpy_is_valid (PyObject
*self
, PyObject
*args
)
383 const struct block
*block
;
385 block
= block_object_to_block (self
);
392 /* Implementation of gdb.BlockIterator.is_valid (self) -> Boolean.
393 Returns True if this block iterator object still exists in GDB */
396 blpy_iter_is_valid (PyObject
*self
, PyObject
*args
)
398 block_syms_iterator_object
*iter_obj
=
399 (block_syms_iterator_object
*) self
;
401 if (iter_obj
->source
->block
== NULL
)
407 /* This function is called when an objfile is about to be freed.
408 Invalidate the block as further actions on the block would result
409 in bad data. All access to obj->symbol should be gated by
410 BLPY_REQUIRE_VALID which will raise an exception on invalid
413 del_objfile_blocks (struct objfile
*objfile
, void *datum
)
415 block_object
*obj
= (block_object
*) datum
;
419 block_object
*next
= obj
->next
;
430 void _initialize_py_block ();
432 _initialize_py_block ()
434 /* Register an objfile "free" callback so we can properly
435 invalidate blocks when an object file is about to be
437 blpy_objfile_data_key
438 = register_objfile_data_with_cleanup (NULL
, del_objfile_blocks
);
442 gdbpy_initialize_blocks (void)
444 block_object_type
.tp_new
= PyType_GenericNew
;
445 if (PyType_Ready (&block_object_type
) < 0)
448 block_syms_iterator_object_type
.tp_new
= PyType_GenericNew
;
449 if (PyType_Ready (&block_syms_iterator_object_type
) < 0)
452 if (gdb_pymodule_addobject (gdb_module
, "Block",
453 (PyObject
*) &block_object_type
) < 0)
456 return gdb_pymodule_addobject (gdb_module
, "BlockIterator",
457 (PyObject
*) &block_syms_iterator_object_type
);
462 static PyMethodDef block_object_methods
[] = {
463 { "is_valid", blpy_is_valid
, METH_NOARGS
,
464 "is_valid () -> Boolean.\n\
465 Return true if this block is valid, false if not." },
466 {NULL
} /* Sentinel */
469 static gdb_PyGetSetDef block_object_getset
[] = {
470 { "start", blpy_get_start
, NULL
, "Start address of the block.", NULL
},
471 { "end", blpy_get_end
, NULL
, "End address of the block.", NULL
},
472 { "function", blpy_get_function
, NULL
,
473 "Symbol that names the block, or None.", NULL
},
474 { "superblock", blpy_get_superblock
, NULL
,
475 "Block containing the block, or None.", NULL
},
476 { "global_block", blpy_get_global_block
, NULL
,
477 "Block containing the global block.", NULL
},
478 { "static_block", blpy_get_static_block
, NULL
,
479 "Block containing the static block.", NULL
},
480 { "is_static", blpy_is_static
, NULL
,
481 "Whether this block is a static block.", NULL
},
482 { "is_global", blpy_is_global
, NULL
,
483 "Whether this block is a global block.", NULL
},
484 { NULL
} /* Sentinel */
487 static PyMappingMethods block_object_as_mapping
= {
493 PyTypeObject block_object_type
= {
494 PyVarObject_HEAD_INIT (NULL
, 0)
495 "gdb.Block", /*tp_name*/
496 sizeof (block_object
), /*tp_basicsize*/
498 blpy_dealloc
, /*tp_dealloc*/
505 0, /*tp_as_sequence*/
506 &block_object_as_mapping
, /*tp_as_mapping*/
513 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_ITER
, /*tp_flags*/
514 "GDB block object", /* tp_doc */
517 0, /* tp_richcompare */
518 0, /* tp_weaklistoffset */
519 blpy_iter
, /* tp_iter */
521 block_object_methods
, /* tp_methods */
523 block_object_getset
/* tp_getset */
526 static PyMethodDef block_iterator_object_methods
[] = {
527 { "is_valid", blpy_iter_is_valid
, METH_NOARGS
,
528 "is_valid () -> Boolean.\n\
529 Return true if this block iterator is valid, false if not." },
530 {NULL
} /* Sentinel */
533 PyTypeObject block_syms_iterator_object_type
= {
534 PyVarObject_HEAD_INIT (NULL
, 0)
535 "gdb.BlockIterator", /*tp_name*/
536 sizeof (block_syms_iterator_object
), /*tp_basicsize*/
538 blpy_block_syms_dealloc
, /*tp_dealloc*/
545 0, /*tp_as_sequence*/
553 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_ITER
, /*tp_flags*/
554 "GDB block syms iterator object", /*tp_doc */
557 0, /*tp_richcompare */
558 0, /*tp_weaklistoffset */
559 blpy_block_syms_iter
, /*tp_iter */
560 blpy_block_syms_iternext
, /*tp_iternext */
561 block_iterator_object_methods
/*tp_methods */