GDB (xrefs)
Loading...
Searching...
No Matches
py-block.c
Go to the documentation of this file.
1/* Python interface to blocks.
2
3 Copyright (C) 2008-2023 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 "defs.h"
21#include "block.h"
22#include "dictionary.h"
23#include "symtab.h"
24#include "python-internal.h"
25#include "objfiles.h"
26
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. */
35 /* Keep track of all blocks with a doubly-linked list. Needed for
36 block invalidation if the source object file has been freed. */
39};
40
42 PyObject_HEAD
43 /* The block. */
44 const struct block *block;
45 /* The iterator for that block. */
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. */
53};
54
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)
67
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)
79
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. */
86{
88 {
89 while (obj)
90 {
91 block_object *next = obj->next;
92
93 obj->block = NULL;
94 obj->objfile = NULL;
95 obj->next = NULL;
96 obj->prev = NULL;
97
98 obj = next;
99 }
100 }
101};
102
103extern PyTypeObject block_syms_iterator_object_type
104 CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("block_syms_iterator_object");
107
108static PyObject *
110{
111 block_syms_iterator_object *block_iter_obj;
112 const struct block *block = NULL;
113
115
116 block_iter_obj = PyObject_New (block_syms_iterator_object,
118 if (block_iter_obj == NULL)
119 return NULL;
120
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;
125
126 return (PyObject *) block_iter_obj;
127}
128
129static PyObject *
130blpy_get_start (PyObject *self, void *closure)
131{
132 const struct block *block = NULL;
133
135
136 return gdb_py_object_from_ulongest (block->start ()).release ();
137}
138
139static PyObject *
140blpy_get_end (PyObject *self, void *closure)
141{
142 const struct block *block = NULL;
143
145
146 return gdb_py_object_from_ulongest (block->end ()).release ();
147}
148
149static PyObject *
150blpy_get_function (PyObject *self, void *closure)
151{
152 struct symbol *sym;
153 const struct block *block;
154
156
157 sym = block->function ();
158 if (sym)
159 return symbol_to_symbol_object (sym);
160
161 Py_RETURN_NONE;
162}
163
164static PyObject *
165blpy_get_superblock (PyObject *self, void *closure)
166{
167 const struct block *block;
168 const struct block *super_block;
169 block_object *self_obj = (block_object *) self;
170
172
173 super_block = block->superblock ();
174 if (super_block)
175 return block_to_block_object (super_block, self_obj->objfile);
176
177 Py_RETURN_NONE;
178}
179
180/* Return the global block associated to this block. */
181
182static PyObject *
183blpy_get_global_block (PyObject *self, void *closure)
184{
185 const struct block *block;
186 const struct block *global_block;
187 block_object *self_obj = (block_object *) self;
188
190
192
194 self_obj->objfile);
195
196}
197
198/* Return the static block associated to this block. Return None
199 if we cannot get the static block (this is the global block). */
200
201static PyObject *
202blpy_get_static_block (PyObject *self, void *closure)
203{
204 const struct block *block;
205 const struct block *static_block;
206 block_object *self_obj = (block_object *) self;
207
209
210 if (block->superblock () == NULL)
211 Py_RETURN_NONE;
212
214
215 return block_to_block_object (static_block, self_obj->objfile);
216}
217
218/* Implementation of gdb.Block.is_global (self) -> Boolean.
219 Returns True if this block object is a global block. */
220
221static PyObject *
222blpy_is_global (PyObject *self, void *closure)
223{
224 const struct block *block;
225
227
228 if (block->superblock ())
229 Py_RETURN_FALSE;
230
231 Py_RETURN_TRUE;
232}
233
234/* Implementation of gdb.Block.is_static (self) -> Boolean.
235 Returns True if this block object is a static block. */
236
237static PyObject *
238blpy_is_static (PyObject *self, void *closure)
239{
240 const struct block *block;
241
243
244 if (block->superblock () != NULL
245 && block->superblock ()->superblock () == NULL)
246 Py_RETURN_TRUE;
247
248 Py_RETURN_FALSE;
249}
250
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. */
254
255static PyObject *
257{
258 const struct block *block;
259
261
262 gdb::unique_xmalloc_ptr<char> name = python_string_to_host_string (key);
263 if (name == nullptr)
264 return nullptr;
265
267
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))
273 {
274 /* Just stop at the first match */
275 return symbol_to_symbol_object (sym);
276 }
277
278 PyErr_SetObject (PyExc_KeyError, key);
279 return nullptr;
280}
281
282static void
284{
286
287 if (block->prev)
288 block->prev->next = block->next;
289 else if (block->objfile)
291 if (block->next)
292 block->next->prev = block->prev;
293 block->block = NULL;
294 Py_TYPE (obj)->tp_free (obj);
295}
296
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. */
302static void
303set_block (block_object *obj, const struct block *block,
304 struct objfile *objfile)
305{
306 obj->block = block;
307 obj->prev = NULL;
308 if (objfile)
309 {
310 obj->objfile = objfile;
312 if (obj->next)
313 obj->next->prev = obj;
315 }
316 else
317 obj->next = NULL;
318}
319
320/* Create a new block object (gdb.Block) that encapsulates the struct
321 block object from GDB. */
322PyObject *
324{
325 block_object *block_obj;
326
327 block_obj = PyObject_New (block_object, &block_object_type);
328 if (block_obj)
329 set_block (block_obj, block, objfile);
330
331 return (PyObject *) block_obj;
332}
333
334/* Return struct block reference that is wrapped by this object. */
335const struct block *
337{
338 if (! PyObject_TypeCheck (obj, &block_object_type))
339 return NULL;
340 return ((block_object *) obj)->block;
341}
342
343/* Return a reference to the block iterator. */
344static PyObject *
346{
348
350
351 Py_INCREF (self);
352 return self;
353}
354
355/* Return the next symbol in the iteration through the block's
356 dictionary. */
357static PyObject *
359{
361 struct symbol *sym;
362
364
365 if (!iter_obj->initialized_p)
366 {
367 sym = block_iterator_first (iter_obj->block, &(iter_obj->iter));
368 iter_obj->initialized_p = 1;
369 }
370 else
371 sym = block_iterator_next (&(iter_obj->iter));
372
373 if (sym == NULL)
374 {
375 PyErr_SetString (PyExc_StopIteration, _("Symbol is null."));
376 return NULL;
377 }
378
379 return symbol_to_symbol_object (sym);
380}
381
382static void
384{
386
387 Py_XDECREF (iter_obj->source);
388 Py_TYPE (obj)->tp_free (obj);
389}
390
391/* Implementation of gdb.Block.is_valid (self) -> Boolean.
392 Returns True if this block object still exists in GDB. */
393
394static PyObject *
396{
397 const struct block *block;
398
400 if (block == NULL)
401 Py_RETURN_FALSE;
402
403 Py_RETURN_TRUE;
404}
405
406/* Implementation of gdb.BlockIterator.is_valid (self) -> Boolean.
407 Returns True if this block iterator object still exists in GDB */
408
409static PyObject *
411{
414
415 if (iter_obj->source->block == NULL)
416 Py_RETURN_FALSE;
417
418 Py_RETURN_TRUE;
419}
420
421/* __repr__ implementation for gdb.Block. */
422
423static PyObject *
425{
426 const auto block = block_object_to_block (self);
427 if (block == nullptr)
428 return PyUnicode_FromFormat ("<%s (invalid)>", Py_TYPE (self)->tp_name);
429
430 const auto name = block->function () ?
431 block->function ()->print_name () : "<anonymous>";
432
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))
438 {
439 if (written_symbols == SYMBOLS_TO_SHOW)
440 {
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;
447 }
448 str += symbol->print_name ();
449 if (++written_symbols < len)
450 str += ", ";
451 }
452 return PyUnicode_FromFormat ("<%s %s {%s}>", Py_TYPE (self)->tp_name,
453 name, str.c_str ());
454}
455
458{
459 block_object_type.tp_new = PyType_GenericNew;
460 if (PyType_Ready (&block_object_type) < 0)
461 return -1;
462
463 block_syms_iterator_object_type.tp_new = PyType_GenericNew;
464 if (PyType_Ready (&block_syms_iterator_object_type) < 0)
465 return -1;
466
468 (PyObject *) &block_object_type) < 0)
469 return -1;
470
471 return gdb_pymodule_addobject (gdb_module, "BlockIterator",
473}
474
476
477
478
479static PyMethodDef block_object_methods[] = {
480 { "is_valid", blpy_is_valid, METH_NOARGS,
481 "is_valid () -> Boolean.\n\
482Return true if this block is valid, false if not." },
483 {NULL} /* Sentinel */
484};
485
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 */
502};
503
504static PyMappingMethods block_object_as_mapping = {
505 NULL,
507 NULL
508};
509
510PyTypeObject 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 */
541};
542
543static PyMethodDef block_iterator_object_methods[] = {
544 { "is_valid", blpy_iter_is_valid, METH_NOARGS,
545 "is_valid () -> Boolean.\n\
546Return true if this block iterator is valid, false if not." },
547 {NULL} /* Sentinel */
548};
549
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 */
579};
const char *const name
struct symbol * block_iterator_first(const struct block *block, struct block_iterator *iterator, const lookup_name_info *name)
Definition block.c:589
struct symbol * block_iterator_next(struct block_iterator *iterator)
Definition block.c:614
iterator_range< block_iterator_wrapper > block_iterator_range
Definition block.h:553
void set(unsigned key, void *datum)
Definition registry.h:204
void * get(unsigned key)
Definition registry.h:211
int mdict_size(const struct multidictionary *mdict)
static PyObject * blpy_getitem(PyObject *self, PyObject *key)
Definition py-block.c:256
PyObject * block_to_block_object(const struct block *block, struct objfile *objfile)
Definition py-block.c:323
static PyObject * blpy_get_static_block(PyObject *self, void *closure)
Definition py-block.c:202
static PyObject * blpy_get_global_block(PyObject *self, void *closure)
Definition py-block.c:183
PyTypeObject block_object_type
Definition py-block.c:510
static void set_block(block_object *obj, const struct block *block, struct objfile *objfile)
Definition py-block.c:303
static PyObject * blpy_block_syms_iter(PyObject *self)
Definition py-block.c:345
static PyObject * blpy_is_valid(PyObject *self, PyObject *args)
Definition py-block.c:395
static int CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION gdbpy_initialize_blocks(void)
Definition py-block.c:457
static PyMethodDef block_iterator_object_methods[]
Definition py-block.c:543
static PyObject * blpy_is_global(PyObject *self, void *closure)
Definition py-block.c:222
static PyObject * blpy_block_syms_iternext(PyObject *self)
Definition py-block.c:358
static PyObject * blpy_get_function(PyObject *self, void *closure)
Definition py-block.c:150
PyTypeObject block_syms_iterator_object_type
Definition py-block.c:550
#define BLPY_REQUIRE_VALID(block_obj, block)
Definition py-block.c:57
static PyMappingMethods block_object_as_mapping
Definition py-block.c:504
static void blpy_dealloc(PyObject *obj)
Definition py-block.c:283
static PyObject * blpy_get_start(PyObject *self, void *closure)
Definition py-block.c:130
static PyObject * blpy_repr(PyObject *self)
Definition py-block.c:424
static PyObject * blpy_get_end(PyObject *self, void *closure)
Definition py-block.c:140
static gdb_PyGetSetDef block_object_getset[]
Definition py-block.c:486
#define BLPY_ITER_REQUIRE_VALID(block_obj)
Definition py-block.c:70
const struct block * block_object_to_block(PyObject *obj)
Definition py-block.c:336
static PyObject * blpy_iter(PyObject *self)
Definition py-block.c:109
static PyObject * blpy_get_superblock(PyObject *self, void *closure)
Definition py-block.c:165
static PyObject * blpy_is_static(PyObject *self, void *closure)
Definition py-block.c:238
static void blpy_block_syms_dealloc(PyObject *obj)
Definition py-block.c:383
static PyObject * blpy_iter_is_valid(PyObject *self, PyObject *args)
Definition py-block.c:410
static PyMethodDef block_object_methods[]
Definition py-block.c:479
static const registry< objfile >::key< block_object, blpy_deleter > blpy_objfile_data_key
Definition py-block.c:106
PyObject * symbol_to_symbol_object(struct symbol *sym)
Definition py-symbol.c:344
int gdb_pymodule_addobject(PyObject *module, const char *name, PyObject *object)
Definition py-utils.c:334
gdb::unique_xmalloc_ptr< char > python_string_to_host_string(PyObject *obj)
Definition py-utils.c:142
gdbpy_ref gdb_py_object_from_ulongest(ULONGEST l)
Definition py-utils.c:293
PyObject * gdb_module
#define CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF(ARG)
#define CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION
#define GDBPY_INITIALIZE_FILE(INIT,...)
block_object * next
Definition py-block.c:38
block_object * prev
Definition py-block.c:37
PyObject_HEAD const struct block * block
Definition py-block.c:30
struct objfile * objfile
Definition py-block.c:34
struct block_iterator iter
Definition py-block.c:46
block_object * source
Definition py-block.c:52
PyObject_HEAD const struct block * block
Definition py-block.c:44
Definition block.h:109
const block * superblock() const
Definition block.h:135
multidictionary * multidict() const
Definition block.h:143
const struct block * global_block() const
Definition block.c:369
CORE_ADDR start() const
Definition block.h:111
const struct block * static_block() const
Definition block.c:354
CORE_ADDR end() const
Definition block.h:119
symbol * function() const
Definition block.h:127
struct objfile * objfile() const
Definition block.c:43
void operator()(block_object *obj)
Definition py-block.c:87
const char * print_name() const
Definition symtab.h:475
int PyObject
Definition varobj.c:41