Add a new class gdb.Architecture which exposes GDB's
internal representation of architecture via GDB Python API. * Makefile.in: Add entries corresponding to the new file python/py-arch.c. * NEWS (Python Scripting): Add entries for the new class gdb.Architecture and the new method gdb.Frame.architecture. * python/py-arch.c: Implement gdb.Architecture class. * python/py-frame.c (frapy_arch): Implement the method gdb.Frame.architecture(). (frame_object_methods): Add 'architecture' to the method table. * python/python-internal.h: Add declarations of new utility functions. * python/python.c (_initialize_python): Initialize gdb.Architecture class. * doc/gdb.texinfo (Architectures In Python): New sub-sub-section describing the gdb.Architecture class. (Frames In Python): Add description about the new method gdb.Frame.architecture(). * testsuite/gdb.python/frame.exp: Add a test for gdb.Frame.architecture() method.
This commit is contained in:
parent
796a7ff823
commit
bea883fd92
11 changed files with 241 additions and 0 deletions
|
@ -1,3 +1,20 @@
|
||||||
|
2013-01-23 Siva Chandra Reddy <sivachandra@google.com>
|
||||||
|
|
||||||
|
Add a new class gdb.Architecture which exposes GDB's
|
||||||
|
internal representation of architecture via GDB Python API.
|
||||||
|
* Makefile.in: Add entries corresponding to the new file
|
||||||
|
python/py-arch.c.
|
||||||
|
* NEWS (Python Scripting): Add entries for the new class
|
||||||
|
gdb.Architecture and the new method gdb.Frame.architecture.
|
||||||
|
* python/py-arch.c: Implement gdb.Architecture class.
|
||||||
|
* python/py-frame.c (frapy_arch): Implement the method
|
||||||
|
gdb.Frame.architecture().
|
||||||
|
(frame_object_methods): Add 'architecture' to the method table.
|
||||||
|
* python/python-internal.h: Add declarations of new utility
|
||||||
|
functions.
|
||||||
|
* python/python.c (_initialize_python): Initialize
|
||||||
|
gdb.Architecture class.
|
||||||
|
|
||||||
2013-01-23 Doug Evans <dje@google.com>
|
2013-01-23 Doug Evans <dje@google.com>
|
||||||
|
|
||||||
Work around binutils/15021.
|
Work around binutils/15021.
|
||||||
|
|
|
@ -271,6 +271,7 @@ SUBDIR_TUI_CFLAGS= \
|
||||||
#
|
#
|
||||||
SUBDIR_PYTHON_OBS = \
|
SUBDIR_PYTHON_OBS = \
|
||||||
python.o \
|
python.o \
|
||||||
|
py-arch.o \
|
||||||
py-auto-load.o \
|
py-auto-load.o \
|
||||||
py-block.o \
|
py-block.o \
|
||||||
py-bpevent.o \
|
py-bpevent.o \
|
||||||
|
@ -304,6 +305,7 @@ SUBDIR_PYTHON_OBS = \
|
||||||
|
|
||||||
SUBDIR_PYTHON_SRCS = \
|
SUBDIR_PYTHON_SRCS = \
|
||||||
python/python.c \
|
python/python.c \
|
||||||
|
python/py-arch.c \
|
||||||
python/py-auto-load.c \
|
python/py-auto-load.c \
|
||||||
python/py-block.c \
|
python/py-block.c \
|
||||||
python/py-bpevent.c \
|
python/py-bpevent.c \
|
||||||
|
@ -2047,6 +2049,10 @@ python.o: $(srcdir)/python/python.c
|
||||||
$(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/python.c
|
$(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/python.c
|
||||||
$(POSTCOMPILE)
|
$(POSTCOMPILE)
|
||||||
|
|
||||||
|
py-arch.o: $(srcdir)/python/py-arch.c
|
||||||
|
$(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-arch.c
|
||||||
|
$(POSTCOMPILE)
|
||||||
|
|
||||||
py-auto-load.o: $(srcdir)/python/py-auto-load.c
|
py-auto-load.o: $(srcdir)/python/py-auto-load.c
|
||||||
$(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-auto-load.c
|
$(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-auto-load.c
|
||||||
$(POSTCOMPILE)
|
$(POSTCOMPILE)
|
||||||
|
|
6
gdb/NEWS
6
gdb/NEWS
|
@ -39,6 +39,12 @@ Lynx 178 PowerPC powerpc-*-lynx*178
|
||||||
|
|
||||||
** Python 3 is now supported (in addition to Python 2.4 or later)
|
** Python 3 is now supported (in addition to Python 2.4 or later)
|
||||||
|
|
||||||
|
** New class gdb.Architecture exposes GDB's internal representation
|
||||||
|
of architecture in the Python API.
|
||||||
|
|
||||||
|
** New method Frame.architecture returns the gdb.Architecture object
|
||||||
|
corresponding to the frame's architecture.
|
||||||
|
|
||||||
* New Python-based convenience functions:
|
* New Python-based convenience functions:
|
||||||
|
|
||||||
** $_memeq(buf1, buf2, length)
|
** $_memeq(buf1, buf2, length)
|
||||||
|
|
|
@ -1,3 +1,10 @@
|
||||||
|
2013-01-23 Siva Chandra Reddy <sivachandra@google.com>
|
||||||
|
|
||||||
|
* doc/gdb.texinfo (Architectures In Python): New sub-sub-section
|
||||||
|
describing the gdb.Architecture class.
|
||||||
|
(Frames In Python): Add description about the new method
|
||||||
|
gdb.Frame.architecture().
|
||||||
|
|
||||||
2013-01-23 Doug Evans <dje@google.com>
|
2013-01-23 Doug Evans <dje@google.com>
|
||||||
|
|
||||||
* gdb.texinfo (Index Section Format): Document .gdb_index version 8.
|
* gdb.texinfo (Index Section Format): Document .gdb_index version 8.
|
||||||
|
|
|
@ -22807,6 +22807,7 @@ situation, a Python @code{KeyboardInterrupt} exception is thrown.
|
||||||
* Finish Breakpoints in Python:: Setting Breakpoints on function return
|
* Finish Breakpoints in Python:: Setting Breakpoints on function return
|
||||||
using Python.
|
using Python.
|
||||||
* Lazy Strings In Python:: Python representation of lazy strings.
|
* Lazy Strings In Python:: Python representation of lazy strings.
|
||||||
|
* Architectures In Python:: Python representation of architectures.
|
||||||
@end menu
|
@end menu
|
||||||
|
|
||||||
@node Basic Python
|
@node Basic Python
|
||||||
|
@ -25110,6 +25111,11 @@ Returns the function name of the frame, or @code{None} if it can't be
|
||||||
obtained.
|
obtained.
|
||||||
@end defun
|
@end defun
|
||||||
|
|
||||||
|
@defun Frame.architecture ()
|
||||||
|
Returns the @code{gdb.Architecture} object corresponding to the frame's
|
||||||
|
architecture. @xref{Architectures In Python}.
|
||||||
|
@end defun
|
||||||
|
|
||||||
@defun Frame.type ()
|
@defun Frame.type ()
|
||||||
Returns the type of the frame. The value can be one of:
|
Returns the type of the frame. The value can be one of:
|
||||||
@table @code
|
@table @code
|
||||||
|
@ -25972,6 +25978,20 @@ resolve this to the lazy string's character type, use the type's
|
||||||
writable.
|
writable.
|
||||||
@end defvar
|
@end defvar
|
||||||
|
|
||||||
|
@node Architectures In Python
|
||||||
|
@subsubsection Python representation of architectures
|
||||||
|
@cindex Python architectures
|
||||||
|
|
||||||
|
@value{GDBN} uses architecture specific parameters and artifacts in a
|
||||||
|
number of its various computations. An architecture is represented
|
||||||
|
by an instance of the @code{gdb.Architecture} class.
|
||||||
|
|
||||||
|
A @code{gdb.Architecture} class has the following methods:
|
||||||
|
|
||||||
|
@defun Architecture.name ()
|
||||||
|
Return the name (string value) of the architecture.
|
||||||
|
@end defun
|
||||||
|
|
||||||
@node Python Auto-loading
|
@node Python Auto-loading
|
||||||
@subsection Python Auto-loading
|
@subsection Python Auto-loading
|
||||||
@cindex Python auto-loading
|
@cindex Python auto-loading
|
||||||
|
|
149
gdb/python/py-arch.c
Normal file
149
gdb/python/py-arch.c
Normal file
|
@ -0,0 +1,149 @@
|
||||||
|
/* Python interface to architecture
|
||||||
|
|
||||||
|
Copyright (C) 2013 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GDB.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#include "defs.h"
|
||||||
|
#include "gdbarch.h"
|
||||||
|
#include "arch-utils.h"
|
||||||
|
#include "python-internal.h"
|
||||||
|
|
||||||
|
typedef struct arch_object_type_object {
|
||||||
|
PyObject_HEAD
|
||||||
|
struct gdbarch *gdbarch;
|
||||||
|
} arch_object;
|
||||||
|
|
||||||
|
static struct gdbarch_data *arch_object_data = NULL;
|
||||||
|
static PyTypeObject arch_object_type;
|
||||||
|
|
||||||
|
/* Associates an arch_object with GDBARCH as gdbarch_data via the gdbarch
|
||||||
|
post init registration mechanism (gdbarch_data_register_post_init). */
|
||||||
|
|
||||||
|
static void *
|
||||||
|
arch_object_data_init (struct gdbarch *gdbarch)
|
||||||
|
{
|
||||||
|
arch_object *arch_obj = PyObject_New (arch_object, &arch_object_type);
|
||||||
|
|
||||||
|
if (arch_obj == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
arch_obj->gdbarch = gdbarch;
|
||||||
|
|
||||||
|
return (void *) arch_obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns the struct gdbarch value corresponding to the given Python
|
||||||
|
architecture object OBJ. */
|
||||||
|
|
||||||
|
struct gdbarch *
|
||||||
|
arch_object_to_gdbarch (PyObject *obj)
|
||||||
|
{
|
||||||
|
arch_object *py_arch = (arch_object *) obj;
|
||||||
|
|
||||||
|
return py_arch->gdbarch;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns the Python architecture object corresponding to GDBARCH.
|
||||||
|
Returns a new reference to the arch_object associated as data with
|
||||||
|
GDBARCH. */
|
||||||
|
|
||||||
|
PyObject *
|
||||||
|
gdbarch_to_arch_object (struct gdbarch *gdbarch)
|
||||||
|
{
|
||||||
|
PyObject *new_ref = (PyObject *) gdbarch_data (gdbarch, arch_object_data);
|
||||||
|
|
||||||
|
/* new_ref could be NULL if registration of arch_object with GDBARCH failed
|
||||||
|
in arch_object_data_init. */
|
||||||
|
Py_XINCREF (new_ref);
|
||||||
|
|
||||||
|
return new_ref;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Implementation of gdb.Architecture.name (self) -> String.
|
||||||
|
Returns the name of the architecture as a string value. */
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
archpy_name (PyObject *self, PyObject *args)
|
||||||
|
{
|
||||||
|
struct gdbarch *gdbarch = arch_object_to_gdbarch (self);
|
||||||
|
const char *name = (gdbarch_bfd_arch_info (gdbarch))->printable_name;
|
||||||
|
PyObject *py_name = PyString_FromString (name);
|
||||||
|
|
||||||
|
return py_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initializes the Architecture class in the gdb module. */
|
||||||
|
|
||||||
|
void
|
||||||
|
gdbpy_initialize_arch (void)
|
||||||
|
{
|
||||||
|
arch_object_data = gdbarch_data_register_post_init (arch_object_data_init);
|
||||||
|
arch_object_type.tp_new = PyType_GenericNew;
|
||||||
|
if (PyType_Ready (&arch_object_type) < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Py_INCREF (&arch_object_type);
|
||||||
|
PyModule_AddObject (gdb_module, "Architecture",
|
||||||
|
(PyObject *) &arch_object_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyMethodDef arch_object_methods [] = {
|
||||||
|
{ "name", archpy_name, METH_NOARGS,
|
||||||
|
"name () -> String.\n\
|
||||||
|
Return the name of the architecture as a string value." },
|
||||||
|
{NULL} /* Sentinel */
|
||||||
|
};
|
||||||
|
|
||||||
|
static PyTypeObject arch_object_type = {
|
||||||
|
PyVarObject_HEAD_INIT (NULL, 0)
|
||||||
|
"gdb.Architecture", /* tp_name */
|
||||||
|
sizeof (arch_object), /* tp_basicsize */
|
||||||
|
0, /* tp_itemsize */
|
||||||
|
0, /* tp_dealloc */
|
||||||
|
0, /* tp_print */
|
||||||
|
0, /* tp_getattr */
|
||||||
|
0, /* tp_setattr */
|
||||||
|
0, /* tp_compare */
|
||||||
|
0, /* tp_repr */
|
||||||
|
0, /* tp_as_number */
|
||||||
|
0, /* tp_as_sequence */
|
||||||
|
0, /* tp_as_mapping */
|
||||||
|
0, /* tp_hash */
|
||||||
|
0, /* tp_call */
|
||||||
|
0, /* tp_str */
|
||||||
|
0, /* tp_getattro */
|
||||||
|
0, /* tp_setattro */
|
||||||
|
0, /* tp_as_buffer */
|
||||||
|
Py_TPFLAGS_DEFAULT, /* tp_flags */
|
||||||
|
"GDB architecture object", /* tp_doc */
|
||||||
|
0, /* tp_traverse */
|
||||||
|
0, /* tp_clear */
|
||||||
|
0, /* tp_richcompare */
|
||||||
|
0, /* tp_weaklistoffset */
|
||||||
|
0, /* tp_iter */
|
||||||
|
0, /* tp_iternext */
|
||||||
|
arch_object_methods, /* tp_methods */
|
||||||
|
0, /* tp_members */
|
||||||
|
0, /* tp_getset */
|
||||||
|
0, /* tp_base */
|
||||||
|
0, /* tp_dict */
|
||||||
|
0, /* tp_descr_get */
|
||||||
|
0, /* tp_descr_set */
|
||||||
|
0, /* tp_dictoffset */
|
||||||
|
0, /* tp_init */
|
||||||
|
0, /* tp_alloc */
|
||||||
|
};
|
|
@ -167,6 +167,25 @@ frapy_type (PyObject *self, PyObject *args)
|
||||||
return PyInt_FromLong (type);
|
return PyInt_FromLong (type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Implementation of gdb.Frame.architecture (self) -> gdb.Architecture.
|
||||||
|
Returns the frame's architecture as a gdb.Architecture object. */
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
frapy_arch (PyObject *self, PyObject *args)
|
||||||
|
{
|
||||||
|
struct frame_info *frame = NULL; /* Initialize to appease gcc warning. */
|
||||||
|
frame_object *obj = (frame_object *) self;
|
||||||
|
volatile struct gdb_exception except;
|
||||||
|
|
||||||
|
TRY_CATCH (except, RETURN_MASK_ALL)
|
||||||
|
{
|
||||||
|
FRAPY_REQUIRE_VALID (self, frame);
|
||||||
|
}
|
||||||
|
GDB_PY_HANDLE_EXCEPTION (except);
|
||||||
|
|
||||||
|
return gdbarch_to_arch_object (obj->gdbarch);
|
||||||
|
}
|
||||||
|
|
||||||
/* Implementation of gdb.Frame.unwind_stop_reason (self) -> Integer.
|
/* Implementation of gdb.Frame.unwind_stop_reason (self) -> Integer.
|
||||||
Returns one of the gdb.FRAME_UNWIND_* constants. */
|
Returns one of the gdb.FRAME_UNWIND_* constants. */
|
||||||
|
|
||||||
|
@ -632,6 +651,9 @@ Return the function name of the frame, or None if it can't be determined." },
|
||||||
{ "type", frapy_type, METH_NOARGS,
|
{ "type", frapy_type, METH_NOARGS,
|
||||||
"type () -> Integer.\n\
|
"type () -> Integer.\n\
|
||||||
Return the type of the frame." },
|
Return the type of the frame." },
|
||||||
|
{ "architecture", frapy_arch, METH_NOARGS,
|
||||||
|
"architecture () -> gdb.Architecture.\n\
|
||||||
|
Return the architecture of the frame." },
|
||||||
{ "unwind_stop_reason", frapy_unwind_stop_reason, METH_NOARGS,
|
{ "unwind_stop_reason", frapy_unwind_stop_reason, METH_NOARGS,
|
||||||
"unwind_stop_reason () -> Integer.\n\
|
"unwind_stop_reason () -> Integer.\n\
|
||||||
Return the reason why it's not possible to find frames older than this." },
|
Return the reason why it's not possible to find frames older than this." },
|
||||||
|
|
|
@ -250,6 +250,8 @@ PyObject *pspy_get_printers (PyObject *, void *);
|
||||||
PyObject *objfile_to_objfile_object (struct objfile *);
|
PyObject *objfile_to_objfile_object (struct objfile *);
|
||||||
PyObject *objfpy_get_printers (PyObject *, void *);
|
PyObject *objfpy_get_printers (PyObject *, void *);
|
||||||
|
|
||||||
|
PyObject *gdbarch_to_arch_object (struct gdbarch *gdbarch);
|
||||||
|
|
||||||
thread_object *create_thread_object (struct thread_info *tp);
|
thread_object *create_thread_object (struct thread_info *tp);
|
||||||
thread_object *find_thread_object (ptid_t ptid);
|
thread_object *find_thread_object (ptid_t ptid);
|
||||||
PyObject *find_inferior_object (int pid);
|
PyObject *find_inferior_object (int pid);
|
||||||
|
@ -263,6 +265,7 @@ struct type *type_object_to_type (PyObject *obj);
|
||||||
struct symtab *symtab_object_to_symtab (PyObject *obj);
|
struct symtab *symtab_object_to_symtab (PyObject *obj);
|
||||||
struct symtab_and_line *sal_object_to_symtab_and_line (PyObject *obj);
|
struct symtab_and_line *sal_object_to_symtab_and_line (PyObject *obj);
|
||||||
struct frame_info *frame_object_to_frame_info (PyObject *frame_obj);
|
struct frame_info *frame_object_to_frame_info (PyObject *frame_obj);
|
||||||
|
struct gdbarch *arch_object_to_gdbarch (PyObject *obj);
|
||||||
|
|
||||||
void gdbpy_initialize_gdb_readline (void);
|
void gdbpy_initialize_gdb_readline (void);
|
||||||
void gdbpy_initialize_auto_load (void);
|
void gdbpy_initialize_auto_load (void);
|
||||||
|
@ -293,6 +296,7 @@ void gdbpy_initialize_continue_event (void);
|
||||||
void gdbpy_initialize_exited_event (void);
|
void gdbpy_initialize_exited_event (void);
|
||||||
void gdbpy_initialize_thread_event (void);
|
void gdbpy_initialize_thread_event (void);
|
||||||
void gdbpy_initialize_new_objfile_event (void);
|
void gdbpy_initialize_new_objfile_event (void);
|
||||||
|
void gdbpy_initialize_arch (void);
|
||||||
|
|
||||||
struct cleanup *make_cleanup_py_decref (PyObject *py);
|
struct cleanup *make_cleanup_py_decref (PyObject *py);
|
||||||
|
|
||||||
|
|
|
@ -1620,6 +1620,7 @@ message == an error message without a stack will be printed."),
|
||||||
gdbpy_initialize_exited_event ();
|
gdbpy_initialize_exited_event ();
|
||||||
gdbpy_initialize_thread_event ();
|
gdbpy_initialize_thread_event ();
|
||||||
gdbpy_initialize_new_objfile_event () ;
|
gdbpy_initialize_new_objfile_event () ;
|
||||||
|
gdbpy_initialize_arch ();
|
||||||
|
|
||||||
observer_attach_before_prompt (before_prompt_hook);
|
observer_attach_before_prompt (before_prompt_hook);
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
2013-01-23 Siva Chandra Reddy <sivachandra@google.com>
|
||||||
|
|
||||||
|
* testsuite/gdb.python/frame.exp: Add a test for
|
||||||
|
gdb.Frame.architecture() method.
|
||||||
|
|
||||||
2013-01-22 Pedro Alves <palves@redhat.com>
|
2013-01-22 Pedro Alves <palves@redhat.com>
|
||||||
|
|
||||||
* gdb.base/annota1.exp (signal sent): No longer expect
|
* gdb.base/annota1.exp (signal sent): No longer expect
|
||||||
|
|
|
@ -38,6 +38,10 @@ gdb_breakpoint [gdb_get_line_number "Block break here."]
|
||||||
gdb_continue_to_breakpoint "Block break here."
|
gdb_continue_to_breakpoint "Block break here."
|
||||||
gdb_py_test_silent_cmd "python bf1 = gdb.selected_frame ()" "get frame" 0
|
gdb_py_test_silent_cmd "python bf1 = gdb.selected_frame ()" "get frame" 0
|
||||||
|
|
||||||
|
# Test Frame.architecture() method.
|
||||||
|
gdb_py_test_silent_cmd "python show_arch_str = gdb.execute(\"show architecture\", to_string=True)" "show arch" 0
|
||||||
|
gdb_test "python print bf1.architecture().name() in show_arch_str" "True" "test Frame.architecture()"
|
||||||
|
|
||||||
# First test that read_var is unaffected by PR 11036 changes.
|
# First test that read_var is unaffected by PR 11036 changes.
|
||||||
gdb_test "python print (bf1.read_var(\"i\"))" "\"stuff\"" "test i"
|
gdb_test "python print (bf1.read_var(\"i\"))" "\"stuff\"" "test i"
|
||||||
gdb_test "python print (bf1.read_var(\"f\"))" "\"foo\"" "test f"
|
gdb_test "python print (bf1.read_var(\"f\"))" "\"foo\"" "test f"
|
||||||
|
|
Loading…
Reference in a new issue