From bea883fd928f283b41d10b02f2b92f28bfb634cf Mon Sep 17 00:00:00 2001 From: Siva Chandra Reddy Date: Wed, 23 Jan 2013 19:59:13 +0000 Subject: [PATCH] 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. --- gdb/ChangeLog | 17 ++++ gdb/Makefile.in | 6 ++ gdb/NEWS | 6 ++ gdb/doc/ChangeLog | 7 ++ gdb/doc/gdb.texinfo | 20 +++++ gdb/python/py-arch.c | 149 ++++++++++++++++++++++++++++++++++ gdb/python/py-frame.c | 22 +++++ gdb/python/python-internal.h | 4 + gdb/python/python.c | 1 + gdb/testsuite/ChangeLog | 5 ++ gdb/testsuite/gdb.python/py-frame.exp | 4 + 11 files changed, 241 insertions(+) create mode 100644 gdb/python/py-arch.c diff --git a/gdb/ChangeLog b/gdb/ChangeLog index c00bb3b..3ea3218 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,20 @@ +2013-01-23 Siva Chandra Reddy + + 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 Work around binutils/15021. diff --git a/gdb/Makefile.in b/gdb/Makefile.in index 6746e64..68d545e 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -271,6 +271,7 @@ SUBDIR_TUI_CFLAGS= \ # SUBDIR_PYTHON_OBS = \ python.o \ + py-arch.o \ py-auto-load.o \ py-block.o \ py-bpevent.o \ @@ -304,6 +305,7 @@ SUBDIR_PYTHON_OBS = \ SUBDIR_PYTHON_SRCS = \ python/python.c \ + python/py-arch.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) +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) diff --git a/gdb/NEWS b/gdb/NEWS index 5e24418..539ceb9 100644 --- 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) + ** 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) diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog index c09e2ff..373ad45 100644 --- a/gdb/doc/ChangeLog +++ b/gdb/doc/ChangeLog @@ -1,3 +1,10 @@ +2013-01-23 Siva Chandra Reddy + + * 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 * gdb.texinfo (Index Section Format): Document .gdb_index version 8. diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index 61e9190..4b51228 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -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. +* Architectures In Python:: Python representation of architectures. @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 +@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 @@ -25972,6 +25978,20 @@ resolve this to the lazy string's character type, use the type's 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 diff --git a/gdb/python/py-arch.c b/gdb/python/py-arch.c new file mode 100644 index 0000000..edd508f --- /dev/null +++ b/gdb/python/py-arch.c @@ -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 . */ + +#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 */ +}; diff --git a/gdb/python/py-frame.c b/gdb/python/py-frame.c index 4b025db..e2eb9c5 100644 --- a/gdb/python/py-frame.c +++ b/gdb/python/py-frame.c @@ -167,6 +167,25 @@ frapy_type (PyObject *self, PyObject *args) 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. */ @@ -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." }, + { "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." }, diff --git a/gdb/python/python-internal.h b/gdb/python/python-internal.h index 7d52c06..8dff1d7 100644 --- a/gdb/python/python-internal.h +++ b/gdb/python/python-internal.h @@ -250,6 +250,8 @@ PyObject *pspy_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); @@ -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 gdbarch *arch_object_to_gdbarch (PyObject *obj); 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_arch (void); struct cleanup *make_cleanup_py_decref (PyObject *py); diff --git a/gdb/python/python.c b/gdb/python/python.c index b0f71a2..53ddee9 100644 --- a/gdb/python/python.c +++ b/gdb/python/python.c @@ -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_arch (); observer_attach_before_prompt (before_prompt_hook); diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 53f734f..3da0f06 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2013-01-23 Siva Chandra Reddy + + * testsuite/gdb.python/frame.exp: Add a test for + gdb.Frame.architecture() method. + 2013-01-22 Pedro Alves * gdb.base/annota1.exp (signal sent): No longer expect diff --git a/gdb/testsuite/gdb.python/py-frame.exp b/gdb/testsuite/gdb.python/py-frame.exp index aa4d937..806da94 100644 --- a/gdb/testsuite/gdb.python/py-frame.exp +++ b/gdb/testsuite/gdb.python/py-frame.exp @@ -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 +# 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" -- 2.7.4