/* Python interface to blocks.
- Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc.
+ Copyright (C) 2008-2012 Free Software Foundation, Inc.
This file is part of GDB.
typedef struct blpy_block_object {
PyObject_HEAD
/* The GDB block structure that represents a frame's code block. */
- struct block *block;
+ const struct block *block;
/* The backing object file. There is no direct relationship in GDB
between a block and an object file. When a block is created also
store a pointer to the object file for later use. */
typedef struct {
PyObject_HEAD
- /* The block dictionary of symbols. */
- struct dictionary *dict;
- /* The iterator for that dictionary. */
- struct dict_iterator iter;
+ /* The block. */
+ const struct block *block;
+ /* The iterator for that block. */
+ struct block_iterator iter;
/* Has the iterator been initialized flag. */
int initialized_p;
/* Pointer back to the original source block object. Needed to
blpy_iter (PyObject *self)
{
block_syms_iterator_object *block_iter_obj;
- struct block *block = NULL;
+ const struct block *block = NULL;
BLPY_REQUIRE_VALID (self, block);
if (block_iter_obj == NULL)
return NULL;
- block_iter_obj->dict = BLOCK_DICT (block);
+ block_iter_obj->block = block;
block_iter_obj->initialized_p = 0;
Py_INCREF (self);
block_iter_obj->source = (block_object *) self;
static PyObject *
blpy_get_start (PyObject *self, void *closure)
{
- struct block *block = NULL;
+ const struct block *block = NULL;
BLPY_REQUIRE_VALID (self, block);
- return PyLong_FromUnsignedLongLong (BLOCK_START (block));
+ return gdb_py_object_from_ulongest (BLOCK_START (block));
}
static PyObject *
blpy_get_end (PyObject *self, void *closure)
{
- struct block *block = NULL;
+ const struct block *block = NULL;
BLPY_REQUIRE_VALID (self, block);
- return PyLong_FromUnsignedLongLong (BLOCK_END (block));
+ return gdb_py_object_from_ulongest (BLOCK_END (block));
}
static PyObject *
blpy_get_function (PyObject *self, void *closure)
{
struct symbol *sym;
- struct block *block = NULL;
+ const struct block *block;
BLPY_REQUIRE_VALID (self, block);
static PyObject *
blpy_get_superblock (PyObject *self, void *closure)
{
- struct block *block = NULL;
- struct block *super_block = NULL;
+ const struct block *block;
+ const struct block *super_block;
block_object *self_obj = (block_object *) self;
BLPY_REQUIRE_VALID (self, block);
Py_RETURN_NONE;
}
+/* Return the global block associated to this block. */
+
+static PyObject *
+blpy_get_global_block (PyObject *self, void *closure)
+{
+ const struct block *block;
+ const struct block *global_block;
+ block_object *self_obj = (block_object *) self;
+
+ BLPY_REQUIRE_VALID (self, block);
+
+ global_block = block_global_block (block);
+
+ return block_to_block_object (global_block,
+ self_obj->objfile);
+
+}
+
+/* Return the static block associated to this block. Return None
+ if we cannot get the static block (this is the global block). */
+
+static PyObject *
+blpy_get_static_block (PyObject *self, void *closure)
+{
+ const struct block *block;
+ const struct block *static_block;
+ block_object *self_obj = (block_object *) self;
+
+ BLPY_REQUIRE_VALID (self, block);
+
+ if (BLOCK_SUPERBLOCK (block) == NULL)
+ Py_RETURN_NONE;
+
+ static_block = block_static_block (block);
+
+ return block_to_block_object (static_block, self_obj->objfile);
+}
+
+/* Implementation of gdb.Block.is_global (self) -> Boolean.
+ Returns True if this block object is a global block. */
+
+static PyObject *
+blpy_is_global (PyObject *self, void *closure)
+{
+ const struct block *block;
+
+ BLPY_REQUIRE_VALID (self, block);
+
+ if (BLOCK_SUPERBLOCK (block))
+ Py_RETURN_FALSE;
+
+ Py_RETURN_TRUE;
+}
+
+/* Implementation of gdb.Block.is_static (self) -> Boolean.
+ Returns True if this block object is a static block. */
+
+static PyObject *
+blpy_is_static (PyObject *self, void *closure)
+{
+ const struct block *block;
+
+ BLPY_REQUIRE_VALID (self, block);
+
+ if (BLOCK_SUPERBLOCK (block) != NULL
+ && BLOCK_SUPERBLOCK (BLOCK_SUPERBLOCK (block)) == NULL)
+ Py_RETURN_TRUE;
+
+ Py_RETURN_FALSE;
+}
+
static void
blpy_dealloc (PyObject *obj)
{
/* Given a block, and a block_object that has previously been
allocated and initialized, populate the block_object with the
struct block data. Also, register the block_object life-cycle
- with the life-cycle of the the object file associated with this
+ with the life-cycle of the object file associated with this
block, if needed. */
static void
-set_block (block_object *obj, struct block *block,
+set_block (block_object *obj, const struct block *block,
struct objfile *objfile)
{
obj->block = block;
/* Create a new block object (gdb.Block) that encapsulates the struct
block object from GDB. */
PyObject *
-block_to_block_object (struct block *block, struct objfile *objfile)
+block_to_block_object (const struct block *block, struct objfile *objfile)
{
block_object *block_obj;
}
/* Return struct block reference that is wrapped by this object. */
-struct block *
+const struct block *
block_object_to_block (PyObject *obj)
{
if (! PyObject_TypeCheck (obj, &block_object_type))
if (!iter_obj->initialized_p)
{
- sym = dict_iterator_first (iter_obj->dict, &(iter_obj->iter));
+ sym = block_iterator_first (iter_obj->block, &(iter_obj->iter));
iter_obj->initialized_p = 1;
}
else
- sym = dict_iterator_next (&(iter_obj->iter));
+ sym = block_iterator_next (&(iter_obj->iter));
if (sym == NULL)
{
blpy_block_syms_dealloc (PyObject *obj)
{
block_syms_iterator_object *iter_obj = (block_syms_iterator_object *) obj;
+
Py_XDECREF (iter_obj->source);
}
+/* Implementation of gdb.Block.is_valid (self) -> Boolean.
+ Returns True if this block object still exists in GDB. */
+
+static PyObject *
+blpy_is_valid (PyObject *self, PyObject *args)
+{
+ const struct block *block;
+
+ block = block_object_to_block (self);
+ if (block == NULL)
+ Py_RETURN_FALSE;
+
+ Py_RETURN_TRUE;
+}
+
+/* Implementation of gdb.BlockIterator.is_valid (self) -> Boolean.
+ Returns True if this block iterator object still exists in GDB */
+
+static PyObject *
+blpy_iter_is_valid (PyObject *self, PyObject *args)
+{
+ block_syms_iterator_object *iter_obj =
+ (block_syms_iterator_object *) self;
+
+ if (iter_obj->source->block == NULL)
+ Py_RETURN_FALSE;
+
+ Py_RETURN_TRUE;
+}
+
/* Return the innermost lexical block containing the specified pc value,
or 0 if there is none. */
PyObject *
gdbpy_block_for_pc (PyObject *self, PyObject *args)
{
- unsigned PY_LONG_LONG pc;
+ gdb_py_ulongest pc;
struct block *block;
- struct obj_section *section;
- struct symtab *symtab;
- PyObject *sym_obj;
+ struct obj_section *section = NULL;
+ struct symtab *symtab = NULL;
+ volatile struct gdb_exception except;
- if (!PyArg_ParseTuple (args, "K", &pc))
+ if (!PyArg_ParseTuple (args, GDB_PY_LLU_ARG, &pc))
return NULL;
- section = find_pc_mapped_section (pc);
- symtab = find_pc_sect_symtab (pc, section);
+ TRY_CATCH (except, RETURN_MASK_ALL)
+ {
+ section = find_pc_mapped_section (pc);
+ symtab = find_pc_sect_symtab (pc, section);
+ }
+ GDB_PY_HANDLE_EXCEPTION (except);
+
if (!symtab || symtab->objfile == NULL)
{
PyErr_SetString (PyExc_RuntimeError,
del_objfile_blocks (struct objfile *objfile, void *datum)
{
block_object *obj = datum;
+
while (obj)
{
block_object *next = obj->next;
\f
+static PyMethodDef block_object_methods[] = {
+ { "is_valid", blpy_is_valid, METH_NOARGS,
+ "is_valid () -> Boolean.\n\
+Return true if this block is valid, false if not." },
+ {NULL} /* Sentinel */
+};
+
static PyGetSetDef block_object_getset[] = {
{ "start", blpy_get_start, NULL, "Start address of the block.", NULL },
{ "end", blpy_get_end, NULL, "End address of the block.", NULL },
"Symbol that names the block, or None.", NULL },
{ "superblock", blpy_get_superblock, NULL,
"Block containing the block, or None.", NULL },
+ { "global_block", blpy_get_global_block, NULL,
+ "Block containing the global block.", NULL },
+ { "static_block", blpy_get_static_block, NULL,
+ "Block containing the static block.", NULL },
+ { "is_static", blpy_is_static, NULL,
+ "Whether this block is a static block.", NULL },
+ { "is_global", blpy_is_global, NULL,
+ "Whether this block is a global block.", NULL },
{ NULL } /* Sentinel */
};
0, /* tp_weaklistoffset */
blpy_iter, /* tp_iter */
0, /* tp_iternext */
- 0, /* tp_methods */
+ block_object_methods, /* tp_methods */
0, /* tp_members */
block_object_getset /* tp_getset */
};
+static PyMethodDef block_iterator_object_methods[] = {
+ { "is_valid", blpy_iter_is_valid, METH_NOARGS,
+ "is_valid () -> Boolean.\n\
+Return true if this block iterator is valid, false if not." },
+ {NULL} /* Sentinel */
+};
+
static PyTypeObject block_syms_iterator_object_type = {
PyObject_HEAD_INIT (NULL)
0, /*ob_size*/
0, /*tp_weaklistoffset */
blpy_block_syms_iter, /*tp_iter */
blpy_block_syms_iternext, /*tp_iternext */
- 0 /*tp_methods */
+ block_iterator_object_methods /*tp_methods */
};