Add more methods to gdb.Progspace
[deliverable/binutils-gdb.git] / gdb / python / py-block.c
CommitLineData
f3e9a817
PM
1/* Python interface to blocks.
2
e2882c85 3 Copyright (C) 2008-2018 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"
26#include "symtab.h"
27
28typedef struct blpy_block_object {
29 PyObject_HEAD
30 /* The GDB block structure that represents a frame's code block. */
9df2fbc4 31 const struct block *block;
f3e9a817
PM
32 /* The backing object file. There is no direct relationship in GDB
33 between a block and an object file. When a block is created also
34 store a pointer to the object file for later use. */
35 struct objfile *objfile;
36 /* Keep track of all blocks with a doubly-linked list. Needed for
37 block invalidation if the source object file has been freed. */
38 struct blpy_block_object *prev;
39 struct blpy_block_object *next;
40} block_object;
41
42typedef struct {
43 PyObject_HEAD
8157b174
TT
44 /* The block. */
45 const struct block *block;
46 /* The iterator for that block. */
47 struct block_iterator iter;
f3e9a817
PM
48 /* Has the iterator been initialized flag. */
49 int initialized_p;
50 /* Pointer back to the original source block object. Needed to
51 check if the block is still valid, and has not been invalidated
52 when an object file has been freed. */
53 struct blpy_block_object *source;
54} block_syms_iterator_object;
55
56/* Require a valid block. All access to block_object->block should be
57 gated by this call. */
58#define BLPY_REQUIRE_VALID(block_obj, block) \
59 do { \
60 block = block_object_to_block (block_obj); \
61 if (block == NULL) \
62 { \
63 PyErr_SetString (PyExc_RuntimeError, \
64 _("Block is invalid.")); \
65 return NULL; \
66 } \
67 } while (0)
68
69/* Require a valid block. This macro is called during block iterator
70 creation, and at each next call. */
71#define BLPY_ITER_REQUIRE_VALID(block_obj) \
72 do { \
73 if (block_obj->block == NULL) \
74 { \
75 PyErr_SetString (PyExc_RuntimeError, \
76 _("Source block for iterator is invalid.")); \
77 return NULL; \
78 } \
79 } while (0)
80
e36122e9 81extern PyTypeObject block_syms_iterator_object_type
62eec1a5 82 CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("block_syms_iterator_object");
f3e9a817
PM
83static const struct objfile_data *blpy_objfile_data_key;
84
85static PyObject *
86blpy_iter (PyObject *self)
87{
88 block_syms_iterator_object *block_iter_obj;
9df2fbc4 89 const struct block *block = NULL;
f3e9a817
PM
90
91 BLPY_REQUIRE_VALID (self, block);
92
93 block_iter_obj = PyObject_New (block_syms_iterator_object,
94 &block_syms_iterator_object_type);
95 if (block_iter_obj == NULL)
96 return NULL;
97
8157b174 98 block_iter_obj->block = block;
f3e9a817
PM
99 block_iter_obj->initialized_p = 0;
100 Py_INCREF (self);
101 block_iter_obj->source = (block_object *) self;
102
103 return (PyObject *) block_iter_obj;
104}
105
106static PyObject *
107blpy_get_start (PyObject *self, void *closure)
108{
9df2fbc4 109 const struct block *block = NULL;
f3e9a817
PM
110
111 BLPY_REQUIRE_VALID (self, block);
112
74aedc46 113 return gdb_py_object_from_ulongest (BLOCK_START (block));
f3e9a817
PM
114}
115
116static PyObject *
117blpy_get_end (PyObject *self, void *closure)
118{
9df2fbc4 119 const struct block *block = NULL;
f3e9a817
PM
120
121 BLPY_REQUIRE_VALID (self, block);
122
74aedc46 123 return gdb_py_object_from_ulongest (BLOCK_END (block));
f3e9a817
PM
124}
125
126static PyObject *
127blpy_get_function (PyObject *self, void *closure)
128{
129 struct symbol *sym;
9df2fbc4 130 const struct block *block;
f3e9a817
PM
131
132 BLPY_REQUIRE_VALID (self, block);
133
134 sym = BLOCK_FUNCTION (block);
135 if (sym)
136 return symbol_to_symbol_object (sym);
137
138 Py_RETURN_NONE;
139}
140
141static PyObject *
142blpy_get_superblock (PyObject *self, void *closure)
143{
9df2fbc4
PM
144 const struct block *block;
145 const struct block *super_block;
f3e9a817
PM
146 block_object *self_obj = (block_object *) self;
147
148 BLPY_REQUIRE_VALID (self, block);
149
150 super_block = BLOCK_SUPERBLOCK (block);
151 if (super_block)
152 return block_to_block_object (super_block, self_obj->objfile);
153
154 Py_RETURN_NONE;
155}
156
9df2fbc4
PM
157/* Return the global block associated to this block. */
158
159static PyObject *
160blpy_get_global_block (PyObject *self, void *closure)
161{
162 const struct block *block;
163 const struct block *global_block;
164 block_object *self_obj = (block_object *) self;
165
166 BLPY_REQUIRE_VALID (self, block);
167
168 global_block = block_global_block (block);
169
170 return block_to_block_object (global_block,
171 self_obj->objfile);
172
173}
174
175/* Return the static block associated to this block. Return None
176 if we cannot get the static block (this is the global block). */
177
178static PyObject *
179blpy_get_static_block (PyObject *self, void *closure)
180{
181 const struct block *block;
182 const struct block *static_block;
183 block_object *self_obj = (block_object *) self;
184
185 BLPY_REQUIRE_VALID (self, block);
186
187 if (BLOCK_SUPERBLOCK (block) == NULL)
188 Py_RETURN_NONE;
189
190 static_block = block_static_block (block);
191
192 return block_to_block_object (static_block, self_obj->objfile);
193}
194
195/* Implementation of gdb.Block.is_global (self) -> Boolean.
196 Returns True if this block object is a global block. */
197
198static PyObject *
199blpy_is_global (PyObject *self, void *closure)
200{
201 const struct block *block;
202
203 BLPY_REQUIRE_VALID (self, block);
204
205 if (BLOCK_SUPERBLOCK (block))
206 Py_RETURN_FALSE;
207
208 Py_RETURN_TRUE;
209}
210
211/* Implementation of gdb.Block.is_static (self) -> Boolean.
212 Returns True if this block object is a static block. */
213
214static PyObject *
215blpy_is_static (PyObject *self, void *closure)
216{
217 const struct block *block;
218
219 BLPY_REQUIRE_VALID (self, block);
220
221 if (BLOCK_SUPERBLOCK (block) != NULL
222 && BLOCK_SUPERBLOCK (BLOCK_SUPERBLOCK (block)) == NULL)
223 Py_RETURN_TRUE;
224
225 Py_RETURN_FALSE;
226}
227
f3e9a817
PM
228static void
229blpy_dealloc (PyObject *obj)
230{
231 block_object *block = (block_object *) obj;
232
233 if (block->prev)
234 block->prev->next = block->next;
235 else if (block->objfile)
236 {
237 set_objfile_data (block->objfile, blpy_objfile_data_key,
238 block->next);
239 }
240 if (block->next)
241 block->next->prev = block->prev;
242 block->block = NULL;
243}
244
245/* Given a block, and a block_object that has previously been
246 allocated and initialized, populate the block_object with the
247 struct block data. Also, register the block_object life-cycle
b021a221 248 with the life-cycle of the object file associated with this
f3e9a817
PM
249 block, if needed. */
250static void
9df2fbc4 251set_block (block_object *obj, const struct block *block,
f3e9a817
PM
252 struct objfile *objfile)
253{
254 obj->block = block;
255 obj->prev = NULL;
256 if (objfile)
257 {
258 obj->objfile = objfile;
19ba03f4
SM
259 obj->next = ((struct blpy_block_object *)
260 objfile_data (objfile, blpy_objfile_data_key));
f3e9a817
PM
261 if (obj->next)
262 obj->next->prev = obj;
263 set_objfile_data (objfile, blpy_objfile_data_key, obj);
264 }
265 else
266 obj->next = NULL;
267}
268
269/* Create a new block object (gdb.Block) that encapsulates the struct
270 block object from GDB. */
271PyObject *
9df2fbc4 272block_to_block_object (const struct block *block, struct objfile *objfile)
f3e9a817
PM
273{
274 block_object *block_obj;
275
276 block_obj = PyObject_New (block_object, &block_object_type);
277 if (block_obj)
278 set_block (block_obj, block, objfile);
279
280 return (PyObject *) block_obj;
281}
282
283/* Return struct block reference that is wrapped by this object. */
9df2fbc4 284const struct block *
f3e9a817
PM
285block_object_to_block (PyObject *obj)
286{
287 if (! PyObject_TypeCheck (obj, &block_object_type))
288 return NULL;
289 return ((block_object *) obj)->block;
290}
291
292/* Return a reference to the block iterator. */
293static PyObject *
294blpy_block_syms_iter (PyObject *self)
295{
296 block_syms_iterator_object *iter_obj = (block_syms_iterator_object *) self;
297
298 BLPY_ITER_REQUIRE_VALID (iter_obj->source);
299
300 Py_INCREF (self);
301 return self;
302}
303
304/* Return the next symbol in the iteration through the block's
305 dictionary. */
306static PyObject *
307blpy_block_syms_iternext (PyObject *self)
308{
309 block_syms_iterator_object *iter_obj = (block_syms_iterator_object *) self;
310 struct symbol *sym;
311
312 BLPY_ITER_REQUIRE_VALID (iter_obj->source);
313
314 if (!iter_obj->initialized_p)
315 {
8157b174 316 sym = block_iterator_first (iter_obj->block, &(iter_obj->iter));
f3e9a817
PM
317 iter_obj->initialized_p = 1;
318 }
319 else
8157b174 320 sym = block_iterator_next (&(iter_obj->iter));
f3e9a817
PM
321
322 if (sym == NULL)
323 {
044c0f87 324 PyErr_SetString (PyExc_StopIteration, _("Symbol is null."));
f3e9a817
PM
325 return NULL;
326 }
327
328 return symbol_to_symbol_object (sym);
329}
330
331static void
332blpy_block_syms_dealloc (PyObject *obj)
333{
334 block_syms_iterator_object *iter_obj = (block_syms_iterator_object *) obj;
d59b6f6c 335
f3e9a817
PM
336 Py_XDECREF (iter_obj->source);
337}
338
29703da4
PM
339/* Implementation of gdb.Block.is_valid (self) -> Boolean.
340 Returns True if this block object still exists in GDB. */
341
342static PyObject *
343blpy_is_valid (PyObject *self, PyObject *args)
344{
9df2fbc4 345 const struct block *block;
29703da4
PM
346
347 block = block_object_to_block (self);
348 if (block == NULL)
349 Py_RETURN_FALSE;
350
351 Py_RETURN_TRUE;
352}
353
354/* Implementation of gdb.BlockIterator.is_valid (self) -> Boolean.
355 Returns True if this block iterator object still exists in GDB */
356
357static PyObject *
358blpy_iter_is_valid (PyObject *self, PyObject *args)
359{
360 block_syms_iterator_object *iter_obj =
361 (block_syms_iterator_object *) self;
362
363 if (iter_obj->source->block == NULL)
364 Py_RETURN_FALSE;
365
366 Py_RETURN_TRUE;
367}
368
f3e9a817
PM
369/* This function is called when an objfile is about to be freed.
370 Invalidate the block as further actions on the block would result
371 in bad data. All access to obj->symbol should be gated by
372 BLPY_REQUIRE_VALID which will raise an exception on invalid
373 blocks. */
374static void
375del_objfile_blocks (struct objfile *objfile, void *datum)
376{
19ba03f4 377 block_object *obj = (block_object *) datum;
d59b6f6c 378
f3e9a817
PM
379 while (obj)
380 {
381 block_object *next = obj->next;
382
383 obj->block = NULL;
384 obj->objfile = NULL;
385 obj->next = NULL;
386 obj->prev = NULL;
387
388 obj = next;
389 }
390}
391
999633ed 392int
f3e9a817
PM
393gdbpy_initialize_blocks (void)
394{
395 block_object_type.tp_new = PyType_GenericNew;
396 if (PyType_Ready (&block_object_type) < 0)
999633ed 397 return -1;
f3e9a817
PM
398
399 block_syms_iterator_object_type.tp_new = PyType_GenericNew;
400 if (PyType_Ready (&block_syms_iterator_object_type) < 0)
999633ed 401 return -1;
f3e9a817
PM
402
403 /* Register an objfile "free" callback so we can properly
404 invalidate blocks when an object file is about to be
405 deleted. */
406 blpy_objfile_data_key
407 = register_objfile_data_with_cleanup (NULL, del_objfile_blocks);
408
aa36459a
TT
409 if (gdb_pymodule_addobject (gdb_module, "Block",
410 (PyObject *) &block_object_type) < 0)
999633ed 411 return -1;
f3e9a817 412
aa36459a
TT
413 return gdb_pymodule_addobject (gdb_module, "BlockIterator",
414 (PyObject *) &block_syms_iterator_object_type);
f3e9a817
PM
415}
416
417\f
418
29703da4
PM
419static PyMethodDef block_object_methods[] = {
420 { "is_valid", blpy_is_valid, METH_NOARGS,
421 "is_valid () -> Boolean.\n\
422Return true if this block is valid, false if not." },
423 {NULL} /* Sentinel */
424};
425
0d1f4ceb 426static gdb_PyGetSetDef block_object_getset[] = {
f3e9a817
PM
427 { "start", blpy_get_start, NULL, "Start address of the block.", NULL },
428 { "end", blpy_get_end, NULL, "End address of the block.", NULL },
429 { "function", blpy_get_function, NULL,
430 "Symbol that names the block, or None.", NULL },
431 { "superblock", blpy_get_superblock, NULL,
432 "Block containing the block, or None.", NULL },
9df2fbc4
PM
433 { "global_block", blpy_get_global_block, NULL,
434 "Block containing the global block.", NULL },
435 { "static_block", blpy_get_static_block, NULL,
436 "Block containing the static block.", NULL },
437 { "is_static", blpy_is_static, NULL,
438 "Whether this block is a static block.", NULL },
439 { "is_global", blpy_is_global, NULL,
440 "Whether this block is a global block.", NULL },
f3e9a817
PM
441 { NULL } /* Sentinel */
442};
443
444PyTypeObject block_object_type = {
9a27f2c6 445 PyVarObject_HEAD_INIT (NULL, 0)
f3e9a817
PM
446 "gdb.Block", /*tp_name*/
447 sizeof (block_object), /*tp_basicsize*/
448 0, /*tp_itemsize*/
449 blpy_dealloc, /*tp_dealloc*/
450 0, /*tp_print*/
451 0, /*tp_getattr*/
452 0, /*tp_setattr*/
453 0, /*tp_compare*/
454 0, /*tp_repr*/
455 0, /*tp_as_number*/
456 0, /*tp_as_sequence*/
457 0, /*tp_as_mapping*/
458 0, /*tp_hash */
459 0, /*tp_call*/
460 0, /*tp_str*/
461 0, /*tp_getattro*/
462 0, /*tp_setattro*/
463 0, /*tp_as_buffer*/
464 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_ITER, /*tp_flags*/
465 "GDB block object", /* tp_doc */
466 0, /* tp_traverse */
467 0, /* tp_clear */
468 0, /* tp_richcompare */
469 0, /* tp_weaklistoffset */
470 blpy_iter, /* tp_iter */
471 0, /* tp_iternext */
29703da4 472 block_object_methods, /* tp_methods */
f3e9a817
PM
473 0, /* tp_members */
474 block_object_getset /* tp_getset */
475};
476
29703da4
PM
477static PyMethodDef block_iterator_object_methods[] = {
478 { "is_valid", blpy_iter_is_valid, METH_NOARGS,
479 "is_valid () -> Boolean.\n\
480Return true if this block iterator is valid, false if not." },
481 {NULL} /* Sentinel */
482};
483
e36122e9 484PyTypeObject block_syms_iterator_object_type = {
9a27f2c6 485 PyVarObject_HEAD_INIT (NULL, 0)
f3e9a817
PM
486 "gdb.BlockIterator", /*tp_name*/
487 sizeof (block_syms_iterator_object), /*tp_basicsize*/
488 0, /*tp_itemsize*/
489 blpy_block_syms_dealloc, /*tp_dealloc*/
490 0, /*tp_print*/
491 0, /*tp_getattr*/
492 0, /*tp_setattr*/
493 0, /*tp_compare*/
494 0, /*tp_repr*/
495 0, /*tp_as_number*/
496 0, /*tp_as_sequence*/
497 0, /*tp_as_mapping*/
498 0, /*tp_hash */
499 0, /*tp_call*/
500 0, /*tp_str*/
501 0, /*tp_getattro*/
502 0, /*tp_setattro*/
503 0, /*tp_as_buffer*/
504 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_ITER, /*tp_flags*/
505 "GDB block syms iterator object", /*tp_doc */
506 0, /*tp_traverse */
507 0, /*tp_clear */
508 0, /*tp_richcompare */
509 0, /*tp_weaklistoffset */
510 blpy_block_syms_iter, /*tp_iter */
511 blpy_block_syms_iternext, /*tp_iternext */
29703da4 512 block_iterator_object_methods /*tp_methods */
f3e9a817 513};
This page took 1.101737 seconds and 4 git commands to generate.