* [RFC - GDB Python API] New gdb.Architecture class
@ 2013-01-21 14:08 Siva Chandra
2013-01-21 17:09 ` Tom Tromey
0 siblings, 1 reply; 8+ messages in thread
From: Siva Chandra @ 2013-01-21 14:08 UTC (permalink / raw)
To: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 1023 bytes --]
Per suggestion here,
http://sourceware.org/ml/gdb-patches/2013-01/msg00296.html, the
attached patch adds a new class 'gdb.Architecture' with a single
method 'name'. I will add tests and docs after we are OK with the code
changes.
ChangeLog:
2013-01-21 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.
* 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.
(GdbMethods): Add 'current_architecture' to the method table.
Thanks,
Siva Chandra
[-- Attachment #2: gdb_arch_patch_v1.txt --]
[-- Type: text/plain, Size: 10483 bytes --]
diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index 7305e6d..956963e 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 \
@@ -2045,6 +2047,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/python/py-arch.c b/gdb/python/py-arch.c
new file mode 100644
index 0000000..94f89f8
--- /dev/null
+++ b/gdb/python/py-arch.c
@@ -0,0 +1,137 @@
+/* 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 {
+ PyObject_HEAD
+ struct gdbarch *gdbarch;
+} arch_object;
+
+/* 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. */
+
+PyObject *
+gdbarch_to_arch_object (struct gdbarch *gdbarch)
+{
+ arch_object *obj = PyObject_New (arch_object, &arch_object_type);
+ if (obj == NULL)
+ {
+ PyErr_SetString (PyExc_MemoryError,
+ _("Could not allocate architectire object"));
+ return NULL;
+ }
+
+ obj->gdbarch = gdbarch;
+ return (PyObject *) obj;
+}
+
+/* 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 = Py_BuildValue ("s", name);
+
+ return py_name;
+}
+
+/* Implementation of gdb.current_arch () -> gdb.Architecture.
+ Returns the current architecture as a gdb.Architecture object. */
+
+PyObject *
+gdbpy_current_arch (PyObject *self, PyObject *args) {
+ struct gdbarch *curr_arch = get_current_arch ();
+ return gdbarch_to_arch_object (curr_arch);
+}
+
+/* Initializes the Architecture class in the gdb module. */
+
+void
+gdbpy_initialize_arch (void)
+{
+ 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 */
+};
+
+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..b409e3d 100644
--- a/gdb/python/py-frame.c
+++ b/gdb/python/py-frame.c
@@ -167,6 +167,26 @@ 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;
+ enum unwind_stop_reason stop_reason;
+
+ 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 +652,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..22ffa6a 100644
--- a/gdb/python/python-internal.h
+++ b/gdb/python/python-internal.h
@@ -154,6 +154,7 @@ extern PyTypeObject events_object_type;
extern PyTypeObject stop_event_object_type;
extern PyTypeObject breakpoint_object_type;
extern PyTypeObject frame_object_type;
+extern PyTypeObject arch_object_type;
typedef struct breakpoint_object
{
@@ -231,6 +232,7 @@ PyObject *gdbpy_selected_inferior (PyObject *self, PyObject *args);
PyObject *gdbpy_string_to_argv (PyObject *self, PyObject *args);
PyObject *gdbpy_parameter (PyObject *self, PyObject *args);
PyObject *gdbpy_parameter_value (enum var_types type, void *var);
+PyObject *gdbpy_current_arch (PyObject *self, PyObject *args);
char *gdbpy_parse_command_name (const char *name,
struct cmd_list_element ***base_list,
struct cmd_list_element **start_list);
@@ -250,6 +252,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 +267,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 +298,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..4f50cf8 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);
@@ -1822,6 +1823,9 @@ Return the selected thread object." },
{ "selected_inferior", gdbpy_selected_inferior, METH_NOARGS,
"selected_inferior () -> gdb.Inferior.\n\
Return the selected inferior object." },
+ { "current_architecture", gdbpy_current_arch, METH_NOARGS,
+ "current_architecture () -> gdb.Architecture.\n\
+Return the current architecture object." },
{ "inferiors", gdbpy_inferiors, METH_NOARGS,
"inferiors () -> (gdb.Inferior, ...).\n\
Return a tuple containing all inferiors." },
^ permalink raw reply [flat|nested] 8+ messages in thread* Re: [RFC - GDB Python API] New gdb.Architecture class
2013-01-21 14:08 [RFC - GDB Python API] New gdb.Architecture class Siva Chandra
@ 2013-01-21 17:09 ` Tom Tromey
2013-01-22 20:40 ` Siva Chandra
0 siblings, 1 reply; 8+ messages in thread
From: Tom Tromey @ 2013-01-21 17:09 UTC (permalink / raw)
To: Siva Chandra; +Cc: gdb-patches
>>>>> "Siva" == Siva Chandra <sivachandra@google.com> writes:
Siva> http://sourceware.org/ml/gdb-patches/2013-01/msg00296.html, the
Siva> attached patch adds a new class 'gdb.Architecture' with a single
Siva> method 'name'. I will add tests and docs after we are OK with the code
Siva> changes.
I think the basic idea is fine.
I found a few nits in the patch, nothing too serious.
Siva> +struct gdbarch *
Siva> +arch_object_to_gdbarch (PyObject *obj)
Siva> +{
Siva> + arch_object *py_arch = (arch_object *) obj;
Siva> + return py_arch->gdbarch;
Missing newline after declaration.
Siva> +PyObject *
Siva> +gdbarch_to_arch_object (struct gdbarch *gdbarch)
Siva> +{
Siva> + arch_object *obj = PyObject_New (arch_object, &arch_object_type);
Siva> + if (obj == NULL)
Siva> + {
Siva> + PyErr_SetString (PyExc_MemoryError,
Siva> + _("Could not allocate architectire object"));
Siva> + return NULL;
Siva> + }
Siva> +
Siva> + obj->gdbarch = gdbarch;
Siva> + return (PyObject *) obj;
Siva> +}
Likewise.
Also, I think there's no need to call PyErr_SetString here.
Just return NULL; PyObject_New will have already set the error
appropriately.
One other question is whether we care about object identity.
gdbarch_to_arch_object returns a new object each time.
Either way is fine depending on circumstances -- we do both already in
gdb -- but it ought to be an explicit choice.
Siva> +static PyObject *
Siva> +archpy_name (PyObject *self, PyObject *args) {
Wrong brace placement.
Siva> + PyObject *py_name = Py_BuildValue ("s", name);
Siva> +
Siva> + return py_name;
Just use PyString_FromString here.
Siva> +PyObject *
Siva> +gdbpy_current_arch (PyObject *self, PyObject *args) {
Wrong brace placement.
Do we need this function? The "current arch" is kind of a problematic
feature. It is semi-exposed to Python right now, but I think we're
mostly agreed that this was an early mistake.
I think the more desirable approach would be to have arch methods on
the appropriate objects -- Frame, but also whatever else, say maybe
objfile or inferior (I'm not really all that sure...).
Anyway, if you do need it:
Siva> + struct gdbarch *curr_arch = get_current_arch ();
.. then why get_current_arch and not 'python_gdbarch'?
Siva> +static PyObject *
Siva> +frapy_arch (PyObject *self, PyObject *args)
Siva> +{
Siva> + struct frame_info *frame = NULL; /* Initialize to appease gcc warning. */
Siva> + frame_object *obj = (frame_object *) self;
Siva> + volatile struct gdb_exception except;
Siva> + enum unwind_stop_reason stop_reason;
I didn't see a use of stop_reason.
Siva> +extern PyTypeObject arch_object_type;
This didn't seem to be used outside of the new file, so it could just be
static there.
Tom
^ permalink raw reply [flat|nested] 8+ messages in thread* Re: [RFC - GDB Python API] New gdb.Architecture class
2013-01-21 17:09 ` Tom Tromey
@ 2013-01-22 20:40 ` Siva Chandra
2013-01-22 21:17 ` Tom Tromey
0 siblings, 1 reply; 8+ messages in thread
From: Siva Chandra @ 2013-01-22 20:40 UTC (permalink / raw)
To: Tom Tromey; +Cc: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 2358 bytes --]
Fixed all of Tom's nits in the attached patch. Also, added doc and
NEWS entries in this patch.
On Mon, Jan 21, 2013 at 9:09 AM, Tom Tromey <tromey@redhat.com> wrote:
> One other question is whether we care about object identity.
> gdbarch_to_arch_object returns a new object each time.
> Either way is fine depending on circumstances -- we do both already in
> gdb -- but it ought to be an explicit choice.
In the attached patch, I have made it such a way that if a Python
architecture object exists, then a new reference is returned instead
of a new object. To be frank, the class is so simple that I am not
really sure which is the right approach. But I modified because I
think (as gdbarch pointers do not change) references instead of whole
objects might be more efficient memory wise(?).
Siva> +gdbpy_current_arch (PyObject *self, PyObject *args) {
> Do we need this function? The "current arch" is kind of a problematic
> feature. It is semi-exposed to Python right now, but I think we're
> mostly agreed that this was an early mistake.
The only reason I added this function is because I can have something
to add as tests for the new class! I have removed it now and only have
tests for the new method gdb.Frame.architecture(). Will raise my
questions about get_current_arch() and python_gdbarch in a separate
thread.
2013-01-22 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.
* 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
Frame.architecture().
testsuite/
* gdb.python/frame.exp: Add a test for Frame.architecture()
method.
Thanks,
Siva Chandra
[-- Attachment #2: gdb_arch_patch_v2.txt --]
[-- Type: text/plain, Size: 12609 bytes --]
diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index 7305e6d..956963e 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 \
@@ -2045,6 +2047,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 49d8447..068e54c 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/gdb.texinfo b/gdb/doc/gdb.texinfo
index 728e44b..9e6ae65 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..93774ce
--- /dev/null
+++ b/gdb/python/py-arch.c
@@ -0,0 +1,156 @@
+/* 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;
+ struct arch_object_type_object *next;
+} arch_object;
+
+static arch_object *arch_object_list = NULL;
+static PyTypeObject arch_object_type;
+
+/* 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.
+ If a Python object corresponding to GDBARCH already exists, then returns
+ a new reference to the existing object. */
+
+PyObject *
+gdbarch_to_arch_object (struct gdbarch *gdbarch)
+{
+ arch_object *arch_obj = arch_object_list;
+ PyObject *new_ref;
+
+ /* Lookup if the gdbarch value already has a Python instance. */
+ while (arch_obj)
+ {
+ if (arch_obj->gdbarch == gdbarch)
+ {
+ new_ref = (PyObject *) arch_obj;
+ Py_INCREF (new_ref);
+
+ return new_ref;
+ }
+
+ arch_obj = arch_obj->next;
+ }
+
+ arch_obj = PyObject_New (arch_object, &arch_object_type);
+ if (arch_obj == NULL)
+ return NULL;
+
+ arch_obj->gdbarch = gdbarch;
+ arch_obj->next = arch_object_list;
+ arch_object_list = arch_obj;
+ /* Ref count should be incremented as a reference is also held by the
+ arch_object_list. */
+ new_ref = (PyObject *) arch_obj;
+ Py_INCREF (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_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/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"
^ permalink raw reply [flat|nested] 8+ messages in thread* Re: [RFC - GDB Python API] New gdb.Architecture class
2013-01-22 20:40 ` Siva Chandra
@ 2013-01-22 21:17 ` Tom Tromey
2013-01-23 13:53 ` Siva Chandra
0 siblings, 1 reply; 8+ messages in thread
From: Tom Tromey @ 2013-01-22 21:17 UTC (permalink / raw)
To: Siva Chandra; +Cc: gdb-patches
>>>>> "Siva" == Siva Chandra <sivachandra@google.com> writes:
Siva> In the attached patch, I have made it such a way that if a Python
Siva> architecture object exists, then a new reference is returned instead
Siva> of a new object. To be frank, the class is so simple that I am not
Siva> really sure which is the right approach. But I modified because I
Siva> think (as gdbarch pointers do not change) references instead of whole
Siva> objects might be more efficient memory wise(?).
I don't think I understand the last point.
Anyway, yeah, I'm not sure whether this is worth the effort or not.
Siva> +typedef struct arch_object_type_object {
Siva> + PyObject_HEAD
Siva> + struct gdbarch *gdbarch;
Siva> + struct arch_object_type_object *next;
Siva> +} arch_object;
Siva> +
Siva> +static arch_object *arch_object_list = NULL;
Instead of this I think you can associated the Python object with the
gdbarch using gdbarch_data_register_post_init and gdbarch_data. This
will let you attach the Python representation directly to the gdbarch.
It seems I missed a spot when adding registry.h. Oops.
Tom
^ permalink raw reply [flat|nested] 8+ messages in thread* Re: [RFC - GDB Python API] New gdb.Architecture class
2013-01-22 21:17 ` Tom Tromey
@ 2013-01-23 13:53 ` Siva Chandra
2013-01-23 15:35 ` Tom Tromey
2013-01-23 15:59 ` Eli Zaretskii
0 siblings, 2 replies; 8+ messages in thread
From: Siva Chandra @ 2013-01-23 13:53 UTC (permalink / raw)
To: Tom Tromey; +Cc: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 1573 bytes --]
On Tue, Jan 22, 2013 at 1:17 PM, Tom Tromey <tromey@redhat.com> wrote:
>
> Siva> +typedef struct arch_object_type_object {
> Siva> + PyObject_HEAD
> Siva> + struct gdbarch *gdbarch;
> Siva> + struct arch_object_type_object *next;
> Siva> +} arch_object;
> Siva> +
> Siva> +static arch_object *arch_object_list = NULL;
>
> Instead of this I think you can associated the Python object with the
> gdbarch using gdbarch_data_register_post_init and gdbarch_data. This
> will let you attach the Python representation directly to the gdbarch.
Done in the attached patch.
2013-01-22 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.
* 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
Frame.architecture().
testsuite/
* gdb.python/frame.exp: Add a test for Frame.architecture()
method.
[-- Attachment #2: gdb_arch_patch_v3.txt --]
[-- Type: text/plain, Size: 12500 bytes --]
diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index 7305e6d..956963e 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 \
@@ -2045,6 +2047,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 49d8447..068e54c 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/gdb.texinfo b/gdb/doc/gdb.texinfo
index 728e44b..9e6ae65 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 <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 */
+};
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/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"
^ permalink raw reply [flat|nested] 8+ messages in thread* Re: [RFC - GDB Python API] New gdb.Architecture class
2013-01-23 13:53 ` Siva Chandra
@ 2013-01-23 15:35 ` Tom Tromey
2013-01-23 15:59 ` Eli Zaretskii
1 sibling, 0 replies; 8+ messages in thread
From: Tom Tromey @ 2013-01-23 15:35 UTC (permalink / raw)
To: Siva Chandra; +Cc: gdb-patches
>>>>> "Siva" == Siva Chandra <sivachandra@google.com> writes:
Siva> 2013-01-22 Siva Chandra Reddy <sivachandra@google.com>
Siva> Add a new class gdb.Architecture which exposes GDB's
Siva> internal representation of architecture via GDB Python API.
Siva> * Makefile.in: Add entries corresponding to the new file
Siva> python/py-arch.c.
Siva> * python/py-arch.c: Implement gdb.Architecture class.
Siva> * python/py-frame.c (frapy_arch): Implement the method
Siva> gdb.Frame.architecture().
Siva> (frame_object_methods): Add 'architecture' to the method table.
Siva> * python/python-internal.h: Add declarations of new utility
Siva> functions.
Siva> * python/python.c (_initialize_python): Initialize
Siva> gdb.Architecture class.
Siva> doc/
Siva> * gdb.texinfo (Architectures In Python): New sub-sub-section
Siva> describing the gdb.Architecture class.
Siva> (Frames In Python): Add description about the new method
Siva> Frame.architecture().
Siva> testsuite/
Siva> * gdb.python/frame.exp: Add a test for Frame.architecture()
Siva> method.
The code bits are ok.
It still needs a doc review though.
Tom
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [RFC - GDB Python API] New gdb.Architecture class
2013-01-23 13:53 ` Siva Chandra
2013-01-23 15:35 ` Tom Tromey
@ 2013-01-23 15:59 ` Eli Zaretskii
2013-01-23 21:01 ` Siva Chandra
1 sibling, 1 reply; 8+ messages in thread
From: Eli Zaretskii @ 2013-01-23 15:59 UTC (permalink / raw)
To: Siva Chandra; +Cc: tromey, gdb-patches
> Date: Wed, 23 Jan 2013 05:53:04 -0800
> From: Siva Chandra <sivachandra@google.com>
> Cc: gdb-patches@sourceware.org
>
> Done in the attached patch.
Thanks.
> --- 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)
This part is OK.
> +@defun Frame.architecture ()
> +Returns the @code{gdb.Architecture} object corresponding to the frame's
> +architecture. @xref{Architectures In Python}
^
Period is missing here. Also, please leave 2 spaces between sentences
(here before the "@xref").
OK with that change.
^ permalink raw reply [flat|nested] 8+ messages in thread* Re: [RFC - GDB Python API] New gdb.Architecture class
2013-01-23 15:59 ` Eli Zaretskii
@ 2013-01-23 21:01 ` Siva Chandra
0 siblings, 0 replies; 8+ messages in thread
From: Siva Chandra @ 2013-01-23 21:01 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: tromey, gdb-patches
[-- Attachment #1: Type: text/plain, Size: 454 bytes --]
On Wed, Jan 23, 2013 at 7:59 AM, Eli Zaretskii <eliz@gnu.org> wrote:
>> +@defun Frame.architecture ()
>> +Returns the @code{gdb.Architecture} object corresponding to the frame's
>> +architecture. @xref{Architectures In Python}
> ^
> Period is missing here. Also, please leave 2 spaces between sentences
> (here before the "@xref").
>
> OK with that change.
Thanks, committed after fixing. Patch attached.
[-- Attachment #2: gdb_arch_patch_final.txt --]
[-- Type: text/plain, Size: 13494 bytes --]
Index: Makefile.in
===================================================================
RCS file: /cvs/src/src/gdb/Makefile.in,v
retrieving revision 1.1231
diff -u -p -r1.1231 Makefile.in
--- Makefile.in 21 Jan 2013 18:15:31 -0000 1.1231
+++ Makefile.in 23 Jan 2013 19:45:51 -0000
@@ -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)
Index: NEWS
===================================================================
RCS file: /cvs/src/src/gdb/NEWS,v
retrieving revision 1.564
diff -u -p -r1.564 NEWS
--- NEWS 21 Jan 2013 17:29:39 -0000 1.564
+++ NEWS 23 Jan 2013 19:45:52 -0000
@@ -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)
Index: doc/gdb.texinfo
===================================================================
RCS file: /cvs/src/src/gdb/doc/gdb.texinfo,v
retrieving revision 1.1045
diff -u -p -r1.1045 gdb.texinfo
--- doc/gdb.texinfo 23 Jan 2013 18:47:51 -0000 1.1045
+++ doc/gdb.texinfo 23 Jan 2013 19:45:53 -0000
@@ -22807,6 +22807,7 @@ situation, a Python @code{KeyboardInterr
* 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,
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 charac
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
Index: python/py-arch.c
===================================================================
RCS file: python/py-arch.c
diff -N python/py-arch.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ python/py-arch.c 23 Jan 2013 19:45:53 -0000
@@ -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: python/py-frame.c
===================================================================
RCS file: /cvs/src/src/gdb/python/py-frame.c,v
retrieving revision 1.28
diff -u -p -r1.28 py-frame.c
--- python/py-frame.c 1 Jan 2013 06:33:01 -0000 1.28
+++ python/py-frame.c 23 Jan 2013 19:45:53 -0000
@@ -167,6 +167,25 @@ frapy_type (PyObject *self, PyObject *ar
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, o
{ "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." },
Index: python/python-internal.h
===================================================================
RCS file: /cvs/src/src/gdb/python/python-internal.h,v
retrieving revision 1.61
diff -u -p -r1.61 python-internal.h
--- python/python-internal.h 1 Jan 2013 06:33:02 -0000 1.61
+++ python/python-internal.h 23 Jan 2013 19:45:53 -0000
@@ -250,6 +250,8 @@ PyObject *pspy_get_printers (PyObject *,
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 (PyObje
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 (vo
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);
Index: python/python.c
===================================================================
RCS file: /cvs/src/src/gdb/python/python.c,v
retrieving revision 1.104
diff -u -p -r1.104 python.c
--- python/python.c 1 Jan 2013 06:33:02 -0000 1.104
+++ python/python.c 23 Jan 2013 19:45:53 -0000
@@ -1620,6 +1620,7 @@ message == an error message without a st
gdbpy_initialize_exited_event ();
gdbpy_initialize_thread_event ();
gdbpy_initialize_new_objfile_event () ;
+ gdbpy_initialize_arch ();
observer_attach_before_prompt (before_prompt_hook);
Index: testsuite/gdb.python/py-frame.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.python/py-frame.exp,v
retrieving revision 1.15
diff -u -p -r1.15 py-frame.exp
--- testsuite/gdb.python/py-frame.exp 1 Jan 2013 06:41:26 -0000 1.15
+++ testsuite/gdb.python/py-frame.exp 23 Jan 2013 19:45:53 -0000
@@ -38,6 +38,10 @@ gdb_breakpoint [gdb_get_line_number "Blo
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"
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2013-01-23 21:01 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-01-21 14:08 [RFC - GDB Python API] New gdb.Architecture class Siva Chandra
2013-01-21 17:09 ` Tom Tromey
2013-01-22 20:40 ` Siva Chandra
2013-01-22 21:17 ` Tom Tromey
2013-01-23 13:53 ` Siva Chandra
2013-01-23 15:35 ` Tom Tromey
2013-01-23 15:59 ` Eli Zaretskii
2013-01-23 21:01 ` Siva Chandra
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox