]> Git Repo - binutils.git/blame - gdb/python/py-block.c
Automatic date update in version.in
[binutils.git] / gdb / python / py-block.c
CommitLineData
f3e9a817
PM
1/* Python interface to blocks.
2
4a94e368 3 Copyright (C) 2008-2022 Free Software Foundation, Inc.
f3e9a817
PM
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"
f3e9a817 26
f99b5177 27struct block_object {
f3e9a817
PM
28 PyObject_HEAD
29 /* The GDB block structure that represents a frame's code block. */
9df2fbc4 30 const struct block *block;
f3e9a817
PM
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. */
f99b5177
TT
37 block_object *prev;
38 block_object *next;
39};
f3e9a817 40
f99b5177 41struct block_syms_iterator_object {
f3e9a817 42 PyObject_HEAD
8157b174
TT
43 /* The block. */
44 const struct block *block;
45 /* The iterator for that block. */
46 struct block_iterator iter;
f3e9a817
PM
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. */
f99b5177
TT
52 block_object *source;
53};
f3e9a817
PM
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
08b8a139
TT
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. */
85struct blpy_deleter
86{
87 void operator() (block_object *obj)
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
e36122e9 103extern PyTypeObject block_syms_iterator_object_type
62eec1a5 104 CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("block_syms_iterator_object");
08b8a139
TT
105static const registry<objfile>::key<block_object, blpy_deleter>
106 blpy_objfile_data_key;
f3e9a817
PM
107
108static PyObject *
109blpy_iter (PyObject *self)
110{
111 block_syms_iterator_object *block_iter_obj;
9df2fbc4 112 const struct block *block = NULL;
f3e9a817
PM
113
114 BLPY_REQUIRE_VALID (self, block);
115
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;
120
8157b174 121 block_iter_obj->block = block;
f3e9a817
PM
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{
9df2fbc4 132 const struct block *block = NULL;
f3e9a817
PM
133
134 BLPY_REQUIRE_VALID (self, block);
135
4b8791e1 136 return gdb_py_object_from_ulongest (block->start ()).release ();
f3e9a817
PM
137}
138
139static PyObject *
140blpy_get_end (PyObject *self, void *closure)
141{
9df2fbc4 142 const struct block *block = NULL;
f3e9a817
PM
143
144 BLPY_REQUIRE_VALID (self, block);
145
4b8791e1 146 return gdb_py_object_from_ulongest (block->end ()).release ();
f3e9a817
PM
147}
148
149static PyObject *
150blpy_get_function (PyObject *self, void *closure)
151{
152 struct symbol *sym;
9df2fbc4 153 const struct block *block;
f3e9a817
PM
154
155 BLPY_REQUIRE_VALID (self, block);
156
6c00f721 157 sym = block->function ();
f3e9a817
PM
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{
9df2fbc4
PM
167 const struct block *block;
168 const struct block *super_block;
f3e9a817
PM
169 block_object *self_obj = (block_object *) self;
170
171 BLPY_REQUIRE_VALID (self, block);
172
f135fe72 173 super_block = block->superblock ();
f3e9a817
PM
174 if (super_block)
175 return block_to_block_object (super_block, self_obj->objfile);
176
177 Py_RETURN_NONE;
178}
179
9df2fbc4
PM
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
189 BLPY_REQUIRE_VALID (self, block);
190
191 global_block = block_global_block (block);
192
193 return block_to_block_object (global_block,
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
208 BLPY_REQUIRE_VALID (self, block);
209
f135fe72 210 if (block->superblock () == NULL)
9df2fbc4
PM
211 Py_RETURN_NONE;
212
213 static_block = block_static_block (block);
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
226 BLPY_REQUIRE_VALID (self, block);
227
f135fe72 228 if (block->superblock ())
9df2fbc4
PM
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
242 BLPY_REQUIRE_VALID (self, block);
243
f135fe72
SM
244 if (block->superblock () != NULL
245 && block->superblock ()->superblock () == NULL)
9df2fbc4
PM
246 Py_RETURN_TRUE;
247
248 Py_RETURN_FALSE;
249}
250
0b27c27d
CB
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 *
256blpy_getitem (PyObject *self, PyObject *key)
257{
258 const struct block *block;
259
260 BLPY_REQUIRE_VALID (self, block);
261
262 gdb::unique_xmalloc_ptr<char> name = python_string_to_host_string (key);
263 if (name == nullptr)
264 return nullptr;
265
266 lookup_name_info lookup_name (name.get(), symbol_name_match_type::FULL);
267
268 /* We use ALL_BLOCK_SYMBOLS_WITH_NAME instead of block_lookup_symbol so
269 that we can look up symbols irrespective of the domain, matching the
270 iterator. It would be confusing if the iterator returns symbols you
271 can't find via getitem. */
272 struct block_iterator iter;
273 struct symbol *sym = nullptr;
274 ALL_BLOCK_SYMBOLS_WITH_NAME (block, lookup_name, iter, sym)
275 {
276 /* Just stop at the first match */
277 break;
278 }
279
280 if (sym == nullptr)
281 {
282 PyErr_SetObject (PyExc_KeyError, key);
283 return nullptr;
284 }
285 return symbol_to_symbol_object (sym);
286}
287
f3e9a817
PM
288static void
289blpy_dealloc (PyObject *obj)
290{
291 block_object *block = (block_object *) obj;
292
293 if (block->prev)
294 block->prev->next = block->next;
295 else if (block->objfile)
08b8a139 296 blpy_objfile_data_key.set (block->objfile, block->next);
f3e9a817
PM
297 if (block->next)
298 block->next->prev = block->prev;
299 block->block = NULL;
2e953aca 300 Py_TYPE (obj)->tp_free (obj);
f3e9a817
PM
301}
302
303/* Given a block, and a block_object that has previously been
304 allocated and initialized, populate the block_object with the
305 struct block data. Also, register the block_object life-cycle
b021a221 306 with the life-cycle of the object file associated with this
f3e9a817
PM
307 block, if needed. */
308static void
9df2fbc4 309set_block (block_object *obj, const struct block *block,
f3e9a817
PM
310 struct objfile *objfile)
311{
312 obj->block = block;
313 obj->prev = NULL;
314 if (objfile)
315 {
316 obj->objfile = objfile;
08b8a139 317 obj->next = blpy_objfile_data_key.get (objfile);
f3e9a817
PM
318 if (obj->next)
319 obj->next->prev = obj;
08b8a139 320 blpy_objfile_data_key.set (objfile, obj);
f3e9a817
PM
321 }
322 else
323 obj->next = NULL;
324}
325
326/* Create a new block object (gdb.Block) that encapsulates the struct
327 block object from GDB. */
328PyObject *
9df2fbc4 329block_to_block_object (const struct block *block, struct objfile *objfile)
f3e9a817
PM
330{
331 block_object *block_obj;
332
333 block_obj = PyObject_New (block_object, &block_object_type);
334 if (block_obj)
335 set_block (block_obj, block, objfile);
336
337 return (PyObject *) block_obj;
338}
339
340/* Return struct block reference that is wrapped by this object. */
9df2fbc4 341const struct block *
f3e9a817
PM
342block_object_to_block (PyObject *obj)
343{
344 if (! PyObject_TypeCheck (obj, &block_object_type))
345 return NULL;
346 return ((block_object *) obj)->block;
347}
348
349/* Return a reference to the block iterator. */
350static PyObject *
351blpy_block_syms_iter (PyObject *self)
352{
353 block_syms_iterator_object *iter_obj = (block_syms_iterator_object *) self;
354
355 BLPY_ITER_REQUIRE_VALID (iter_obj->source);
356
357 Py_INCREF (self);
358 return self;
359}
360
361/* Return the next symbol in the iteration through the block's
362 dictionary. */
363static PyObject *
364blpy_block_syms_iternext (PyObject *self)
365{
366 block_syms_iterator_object *iter_obj = (block_syms_iterator_object *) self;
367 struct symbol *sym;
368
369 BLPY_ITER_REQUIRE_VALID (iter_obj->source);
370
371 if (!iter_obj->initialized_p)
372 {
8157b174 373 sym = block_iterator_first (iter_obj->block, &(iter_obj->iter));
f3e9a817
PM
374 iter_obj->initialized_p = 1;
375 }
376 else
8157b174 377 sym = block_iterator_next (&(iter_obj->iter));
f3e9a817
PM
378
379 if (sym == NULL)
380 {
044c0f87 381 PyErr_SetString (PyExc_StopIteration, _("Symbol is null."));
f3e9a817
PM
382 return NULL;
383 }
384
385 return symbol_to_symbol_object (sym);
386}
387
388static void
389blpy_block_syms_dealloc (PyObject *obj)
390{
391 block_syms_iterator_object *iter_obj = (block_syms_iterator_object *) obj;
d59b6f6c 392
f3e9a817 393 Py_XDECREF (iter_obj->source);
2e953aca 394 Py_TYPE (obj)->tp_free (obj);
f3e9a817
PM
395}
396
29703da4
PM
397/* Implementation of gdb.Block.is_valid (self) -> Boolean.
398 Returns True if this block object still exists in GDB. */
399
400static PyObject *
401blpy_is_valid (PyObject *self, PyObject *args)
402{
9df2fbc4 403 const struct block *block;
29703da4
PM
404
405 block = block_object_to_block (self);
406 if (block == NULL)
407 Py_RETURN_FALSE;
408
409 Py_RETURN_TRUE;
410}
411
412/* Implementation of gdb.BlockIterator.is_valid (self) -> Boolean.
413 Returns True if this block iterator object still exists in GDB */
414
415static PyObject *
416blpy_iter_is_valid (PyObject *self, PyObject *args)
417{
418 block_syms_iterator_object *iter_obj =
419 (block_syms_iterator_object *) self;
420
421 if (iter_obj->source->block == NULL)
422 Py_RETURN_FALSE;
423
424 Py_RETURN_TRUE;
425}
426
999633ed 427int
f3e9a817
PM
428gdbpy_initialize_blocks (void)
429{
430 block_object_type.tp_new = PyType_GenericNew;
431 if (PyType_Ready (&block_object_type) < 0)
999633ed 432 return -1;
f3e9a817
PM
433
434 block_syms_iterator_object_type.tp_new = PyType_GenericNew;
435 if (PyType_Ready (&block_syms_iterator_object_type) < 0)
999633ed 436 return -1;
f3e9a817 437
aa36459a
TT
438 if (gdb_pymodule_addobject (gdb_module, "Block",
439 (PyObject *) &block_object_type) < 0)
999633ed 440 return -1;
f3e9a817 441
aa36459a
TT
442 return gdb_pymodule_addobject (gdb_module, "BlockIterator",
443 (PyObject *) &block_syms_iterator_object_type);
f3e9a817
PM
444}
445
446\f
447
29703da4
PM
448static PyMethodDef block_object_methods[] = {
449 { "is_valid", blpy_is_valid, METH_NOARGS,
450 "is_valid () -> Boolean.\n\
451Return true if this block is valid, false if not." },
452 {NULL} /* Sentinel */
453};
454
0d1f4ceb 455static gdb_PyGetSetDef block_object_getset[] = {
f3e9a817
PM
456 { "start", blpy_get_start, NULL, "Start address of the block.", NULL },
457 { "end", blpy_get_end, NULL, "End address of the block.", NULL },
458 { "function", blpy_get_function, NULL,
459 "Symbol that names the block, or None.", NULL },
460 { "superblock", blpy_get_superblock, NULL,
461 "Block containing the block, or None.", NULL },
9df2fbc4
PM
462 { "global_block", blpy_get_global_block, NULL,
463 "Block containing the global block.", NULL },
464 { "static_block", blpy_get_static_block, NULL,
465 "Block containing the static block.", NULL },
466 { "is_static", blpy_is_static, NULL,
467 "Whether this block is a static block.", NULL },
468 { "is_global", blpy_is_global, NULL,
469 "Whether this block is a global block.", NULL },
f3e9a817
PM
470 { NULL } /* Sentinel */
471};
472
0b27c27d
CB
473static PyMappingMethods block_object_as_mapping = {
474 NULL,
475 blpy_getitem,
476 NULL
477};
478
f3e9a817 479PyTypeObject block_object_type = {
9a27f2c6 480 PyVarObject_HEAD_INIT (NULL, 0)
f3e9a817
PM
481 "gdb.Block", /*tp_name*/
482 sizeof (block_object), /*tp_basicsize*/
483 0, /*tp_itemsize*/
484 blpy_dealloc, /*tp_dealloc*/
485 0, /*tp_print*/
486 0, /*tp_getattr*/
487 0, /*tp_setattr*/
488 0, /*tp_compare*/
489 0, /*tp_repr*/
490 0, /*tp_as_number*/
491 0, /*tp_as_sequence*/
0b27c27d 492 &block_object_as_mapping, /*tp_as_mapping*/
f3e9a817
PM
493 0, /*tp_hash */
494 0, /*tp_call*/
495 0, /*tp_str*/
496 0, /*tp_getattro*/
497 0, /*tp_setattro*/
498 0, /*tp_as_buffer*/
0b233e34 499 Py_TPFLAGS_DEFAULT, /*tp_flags*/
f3e9a817
PM
500 "GDB block object", /* tp_doc */
501 0, /* tp_traverse */
502 0, /* tp_clear */
503 0, /* tp_richcompare */
504 0, /* tp_weaklistoffset */
505 blpy_iter, /* tp_iter */
506 0, /* tp_iternext */
29703da4 507 block_object_methods, /* tp_methods */
f3e9a817
PM
508 0, /* tp_members */
509 block_object_getset /* tp_getset */
510};
511
29703da4
PM
512static PyMethodDef block_iterator_object_methods[] = {
513 { "is_valid", blpy_iter_is_valid, METH_NOARGS,
514 "is_valid () -> Boolean.\n\
515Return true if this block iterator is valid, false if not." },
516 {NULL} /* Sentinel */
517};
518
e36122e9 519PyTypeObject block_syms_iterator_object_type = {
9a27f2c6 520 PyVarObject_HEAD_INIT (NULL, 0)
f3e9a817
PM
521 "gdb.BlockIterator", /*tp_name*/
522 sizeof (block_syms_iterator_object), /*tp_basicsize*/
523 0, /*tp_itemsize*/
524 blpy_block_syms_dealloc, /*tp_dealloc*/
525 0, /*tp_print*/
526 0, /*tp_getattr*/
527 0, /*tp_setattr*/
528 0, /*tp_compare*/
529 0, /*tp_repr*/
530 0, /*tp_as_number*/
531 0, /*tp_as_sequence*/
532 0, /*tp_as_mapping*/
533 0, /*tp_hash */
534 0, /*tp_call*/
535 0, /*tp_str*/
536 0, /*tp_getattro*/
537 0, /*tp_setattro*/
538 0, /*tp_as_buffer*/
0b233e34 539 Py_TPFLAGS_DEFAULT, /*tp_flags*/
f3e9a817
PM
540 "GDB block syms iterator object", /*tp_doc */
541 0, /*tp_traverse */
542 0, /*tp_clear */
543 0, /*tp_richcompare */
544 0, /*tp_weaklistoffset */
545 blpy_block_syms_iter, /*tp_iter */
546 blpy_block_syms_iternext, /*tp_iternext */
29703da4 547 block_iterator_object_methods /*tp_methods */
f3e9a817 548};
This page took 3.145076 seconds and 5 git commands to generate.