Add a new class gdb.Architecture which exposes GDB's
authorSiva Chandra Reddy <sivachandra@sourceware.org>
Wed, 23 Jan 2013 19:59:13 +0000 (19:59 +0000)
committerSiva Chandra Reddy <sivachandra@sourceware.org>
Wed, 23 Jan 2013 19:59:13 +0000 (19:59 +0000)
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.

gdb/ChangeLog
gdb/Makefile.in
gdb/NEWS
gdb/doc/ChangeLog
gdb/doc/gdb.texinfo
gdb/python/py-arch.c [new file with mode: 0644]
gdb/python/py-frame.c
gdb/python/python-internal.h
gdb/python/python.c
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.python/py-frame.exp

index c00bb3b..3ea3218 100644 (file)
@@ -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>
 
        Work around binutils/15021.
 2013-01-23  Doug Evans  <dje@google.com>
 
        Work around binutils/15021.
index 6746e64..68d545e 100644 (file)
@@ -271,6 +271,7 @@ SUBDIR_TUI_CFLAGS= \
 #
 SUBDIR_PYTHON_OBS = \
        python.o \
 #
 SUBDIR_PYTHON_OBS = \
        python.o \
+       py-arch.o \
        py-auto-load.o \
        py-block.o \
        py-bpevent.o \
        py-auto-load.o \
        py-block.o \
        py-bpevent.o \
@@ -304,6 +305,7 @@ SUBDIR_PYTHON_OBS = \
 
 SUBDIR_PYTHON_SRCS = \
        python/python.c \
 
 SUBDIR_PYTHON_SRCS = \
        python/python.c \
+       python/py-arch.c \
        python/py-auto-load.c \
        python/py-block.c \
        python/py-bpevent.c \
        python/py-auto-load.c \
        python/py-block.c \
        python/py-bpevent.c \
@@ -2047,6 +2049,10 @@ python.o: $(srcdir)/python/python.c
        $(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/python.c
        $(POSTCOMPILE)
 
        $(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/python.c
        $(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
        $(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-auto-load.c
        $(POSTCOMPILE)
 py-auto-load.o: $(srcdir)/python/py-auto-load.c
        $(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-auto-load.c
        $(POSTCOMPILE)
index 5e24418..539ceb9 100644 (file)
--- a/gdb/NEWS
+++ b/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:
 
   ** $_memeq(buf1, buf2, length)
 * New Python-based convenience functions:
 
   ** $_memeq(buf1, buf2, length)
index c09e2ff..373ad45 100644 (file)
@@ -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>
 
        * gdb.texinfo (Index Section Format): Document .gdb_index version 8.
 2013-01-23  Doug Evans  <dje@google.com>
 
        * gdb.texinfo (Index Section Format): Document .gdb_index version 8.
index 61e9190..4b51228 100644 (file)
@@ -22807,6 +22807,7 @@ situation, a Python @code{KeyboardInterrupt} exception is thrown.
 * Finish Breakpoints in Python:: Setting Breakpoints on function return
                                 using Python.
 * Lazy Strings In Python::      Python representation of lazy strings.
 * Finish Breakpoints in Python:: Setting Breakpoints on function return
                                 using Python.
 * Lazy Strings In Python::      Python representation of lazy strings.
+* Architectures In Python::     Python representation of architectures.
 @end menu
 
 @node Basic Python
 @end menu
 
 @node Basic Python
@@ -25110,6 +25111,11 @@ Returns the function name of the frame, or @code{None} if it can't be
 obtained.
 @end defun
 
 obtained.
 @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 ()
 Returns the type of the frame.  The value can be one of:
 @table @code
 @defun Frame.type ()
 Returns the type of the frame.  The value can be one of:
 @table @code
@@ -25972,6 +25978,20 @@ resolve this to the lazy string's character type, use the type's
 writable.
 @end defvar
 
 writable.
 @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
 @subsection Python Auto-loading
 @cindex Python auto-loading
 @node Python Auto-loading
 @subsection Python Auto-loading
 @cindex Python auto-loading
diff --git a/gdb/python/py-arch.c b/gdb/python/py-arch.c
new file mode 100644 (file)
index 0000000..edd508f
--- /dev/null
@@ -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 */
+};
index 4b025db..e2eb9c5 100644 (file)
@@ -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.
    Returns one of the gdb.FRAME_UNWIND_* constants.  */
 
 /* Implementation of gdb.Frame.unwind_stop_reason (self) -> Integer.
    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 () -> Integer.\n\
 Return the type of the frame." },
   { "type", frapy_type, METH_NOARGS,
     "type () -> Integer.\n\
 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 () -> Integer.\n\
 Return the reason why it's not possible to find frames older than this." },
   { "unwind_stop_reason", frapy_unwind_stop_reason, METH_NOARGS,
     "unwind_stop_reason () -> Integer.\n\
 Return the reason why it's not possible to find frames older than this." },
index 7d52c06..8dff1d7 100644 (file)
@@ -250,6 +250,8 @@ PyObject *pspy_get_printers (PyObject *, void *);
 PyObject *objfile_to_objfile_object (struct objfile *);
 PyObject *objfpy_get_printers (PyObject *, void *);
 
 PyObject *objfile_to_objfile_object (struct objfile *);
 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 *find_thread_object (ptid_t ptid);
 PyObject *find_inferior_object (int pid);
 thread_object *create_thread_object (struct thread_info *tp);
 thread_object *find_thread_object (ptid_t ptid);
 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_and_line *sal_object_to_symtab_and_line (PyObject *obj);
 struct frame_info *frame_object_to_frame_info (PyObject *frame_obj);
 struct symtab *symtab_object_to_symtab (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 gdbarch *arch_object_to_gdbarch (PyObject *obj);
 
 void gdbpy_initialize_gdb_readline (void);
 void gdbpy_initialize_auto_load (void);
 
 void gdbpy_initialize_gdb_readline (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_thread_event (void);
 void gdbpy_initialize_new_objfile_event (void);
 void gdbpy_initialize_exited_event (void);
 void gdbpy_initialize_thread_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);
 
index b0f71a2..53ddee9 100644 (file)
@@ -1620,6 +1620,7 @@ message == an error message without a stack will be printed."),
   gdbpy_initialize_exited_event ();
   gdbpy_initialize_thread_event ();
   gdbpy_initialize_new_objfile_event () ;
   gdbpy_initialize_exited_event ();
   gdbpy_initialize_thread_event ();
   gdbpy_initialize_new_objfile_event () ;
+  gdbpy_initialize_arch ();
 
   observer_attach_before_prompt (before_prompt_hook);
 
 
   observer_attach_before_prompt (before_prompt_hook);
 
index 53f734f..3da0f06 100644 (file)
@@ -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>
 
        * gdb.base/annota1.exp (signal sent): No longer expect
 2013-01-22  Pedro Alves  <palves@redhat.com>
 
        * gdb.base/annota1.exp (signal sent): No longer expect
index aa4d937..806da94 100644 (file)
@@ -38,6 +38,10 @@ gdb_breakpoint [gdb_get_line_number "Block break here."]
 gdb_continue_to_breakpoint "Block break here."
 gdb_py_test_silent_cmd "python bf1 = gdb.selected_frame ()" "get frame" 0
 
 gdb_continue_to_breakpoint "Block break here."
 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.
 gdb_test "python print (bf1.read_var(\"i\"))" "\"stuff\"" "test i"
 gdb_test "python print (bf1.read_var(\"f\"))" "\"foo\"" "test f"
 # 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(\"f\"))" "\"foo\"" "test f"