GDB (API)
/home/stan/gdb/src/gdb/python/py-arch.c
Go to the documentation of this file.
00001 /* Python interface to architecture
00002 
00003    Copyright (C) 2013 Free Software Foundation, Inc.
00004 
00005    This file is part of GDB.
00006 
00007    This program is free software; you can redistribute it and/or modify
00008    it under the terms of the GNU General Public License as published by
00009    the Free Software Foundation; either version 3 of the License, or
00010    (at your option) any later version.
00011 
00012    This program is distributed in the hope that it will be useful,
00013    but WITHOUT ANY WARRANTY; without even the implied warranty of
00014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015    GNU General Public License for more details.
00016 
00017    You should have received a copy of the GNU General Public License
00018    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
00019 
00020 #include "defs.h"
00021 #include "gdbarch.h"
00022 #include "arch-utils.h"
00023 #include "disasm.h"
00024 #include "python-internal.h"
00025 
00026 typedef struct arch_object_type_object {
00027   PyObject_HEAD
00028   struct gdbarch *gdbarch;
00029 } arch_object;
00030 
00031 static struct gdbarch_data *arch_object_data = NULL;
00032 
00033 /* Require a valid Architecture.  */
00034 #define ARCHPY_REQUIRE_VALID(arch_obj, arch)                    \
00035   do {                                                          \
00036     arch = arch_object_to_gdbarch (arch_obj);                   \
00037     if (arch == NULL)                                           \
00038       {                                                         \
00039         PyErr_SetString (PyExc_RuntimeError,                    \
00040                          _("Architecture is invalid."));        \
00041         return NULL;                                            \
00042       }                                                         \
00043   } while (0)
00044 
00045 static PyTypeObject arch_object_type
00046     CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("arch_object");
00047 
00048 /* Associates an arch_object with GDBARCH as gdbarch_data via the gdbarch
00049    post init registration mechanism (gdbarch_data_register_post_init).  */
00050 
00051 static void *
00052 arch_object_data_init (struct gdbarch *gdbarch)
00053 {
00054   arch_object *arch_obj = PyObject_New (arch_object, &arch_object_type);
00055 
00056   if (arch_obj == NULL)
00057     return NULL;
00058 
00059   arch_obj->gdbarch = gdbarch;
00060 
00061   return (void *) arch_obj;
00062 }
00063 
00064 /* Returns the struct gdbarch value corresponding to the given Python
00065    architecture object OBJ.  */
00066 
00067 struct gdbarch *
00068 arch_object_to_gdbarch (PyObject *obj)
00069 {
00070   arch_object *py_arch = (arch_object *) obj;
00071 
00072   return py_arch->gdbarch;
00073 }
00074 
00075 /* Returns the Python architecture object corresponding to GDBARCH.
00076    Returns a new reference to the arch_object associated as data with
00077    GDBARCH.  */
00078 
00079 PyObject *
00080 gdbarch_to_arch_object (struct gdbarch *gdbarch)
00081 {
00082   PyObject *new_ref = (PyObject *) gdbarch_data (gdbarch, arch_object_data);
00083 
00084   /* new_ref could be NULL if registration of arch_object with GDBARCH failed
00085      in arch_object_data_init.  */
00086   Py_XINCREF (new_ref);
00087 
00088   return new_ref;
00089 }
00090 
00091 /* Implementation of gdb.Architecture.name (self) -> String.
00092    Returns the name of the architecture as a string value.  */
00093 
00094 static PyObject *
00095 archpy_name (PyObject *self, PyObject *args)
00096 {
00097   struct gdbarch *gdbarch = NULL;
00098   const char *name;
00099   PyObject *py_name;
00100 
00101   ARCHPY_REQUIRE_VALID (self, gdbarch);
00102 
00103   name = (gdbarch_bfd_arch_info (gdbarch))->printable_name;
00104   py_name = PyString_FromString (name);
00105 
00106   return py_name;
00107 }
00108 
00109 /* Implementation of
00110    gdb.Architecture.disassemble (self, start_pc [, end_pc [,count]]) -> List.
00111    Returns a list of instructions in a memory address range.  Each instruction
00112    in the list is a Python dict object.
00113 */
00114 
00115 static PyObject *
00116 archpy_disassemble (PyObject *self, PyObject *args, PyObject *kw)
00117 {
00118   static char *keywords[] = { "start_pc", "end_pc", "count", NULL };
00119   CORE_ADDR start, end = 0;
00120   CORE_ADDR pc;
00121   gdb_py_ulongest start_temp;
00122   long count = 0, i;
00123   PyObject *result_list, *end_obj = NULL, *count_obj = NULL;
00124   struct gdbarch *gdbarch = NULL;
00125 
00126   ARCHPY_REQUIRE_VALID (self, gdbarch);
00127 
00128   if (!PyArg_ParseTupleAndKeywords (args, kw, GDB_PY_LLU_ARG "|OO", keywords,
00129                                     &start_temp, &end_obj, &count_obj))
00130     return NULL;
00131 
00132   start = start_temp;
00133   if (end_obj)
00134     {
00135       /* Make a long logic check first.  In Python 3.x, internally,
00136          all integers are represented as longs.  In Python 2.x, there
00137          is still a differentiation internally between a PyInt and a
00138          PyLong.  Explicitly do this long check conversion first. In
00139          GDB, for Python 3.x, we #ifdef PyInt = PyLong.  This check has
00140          to be done first to ensure we do not lose information in the
00141          conversion process.  */
00142       if (PyLong_Check (end_obj))
00143         end = PyLong_AsUnsignedLongLong (end_obj);
00144       else if (PyInt_Check (end_obj))
00145         /* If the end_pc value is specified without a trailing 'L', end_obj will
00146            be an integer and not a long integer.  */
00147         end = PyInt_AsLong (end_obj);
00148       else
00149         {
00150           Py_DECREF (end_obj);
00151           Py_XDECREF (count_obj);
00152           PyErr_SetString (PyExc_TypeError,
00153                            _("Argument 'end_pc' should be a (long) integer."));
00154 
00155           return NULL;
00156         }
00157 
00158       if (end < start)
00159         {
00160           Py_DECREF (end_obj);
00161           Py_XDECREF (count_obj);
00162           PyErr_SetString (PyExc_ValueError,
00163                            _("Argument 'end_pc' should be greater than or "
00164                              "equal to the argument 'start_pc'."));
00165 
00166           return NULL;
00167         }
00168     }
00169   if (count_obj)
00170     {
00171       count = PyInt_AsLong (count_obj);
00172       if (PyErr_Occurred () || count < 0)
00173         {
00174           Py_DECREF (count_obj);
00175           Py_XDECREF (end_obj);
00176           PyErr_SetString (PyExc_TypeError,
00177                            _("Argument 'count' should be an non-negative "
00178                              "integer."));
00179 
00180           return NULL;
00181         }
00182     }
00183 
00184   result_list = PyList_New (0);
00185   if (result_list == NULL)
00186     return NULL;
00187 
00188   for (pc = start, i = 0;
00189        /* All args are specified.  */
00190        (end_obj && count_obj && pc <= end && i < count)
00191        /* end_pc is specified, but no count.  */
00192        || (end_obj && count_obj == NULL && pc <= end)
00193        /* end_pc is not specified, but a count is.  */
00194        || (end_obj == NULL && count_obj && i < count)
00195        /* Both end_pc and count are not specified.  */
00196        || (end_obj == NULL && count_obj == NULL && pc == start);)
00197     {
00198       int insn_len = 0;
00199       char *as = NULL;
00200       struct ui_file *memfile = mem_fileopen ();
00201       PyObject *insn_dict = PyDict_New ();
00202       volatile struct gdb_exception except;
00203 
00204       if (insn_dict == NULL)
00205         {
00206           Py_DECREF (result_list);
00207           ui_file_delete (memfile);
00208 
00209           return NULL;
00210         }
00211       if (PyList_Append (result_list, insn_dict))
00212         {
00213           Py_DECREF (result_list);
00214           Py_DECREF (insn_dict);
00215           ui_file_delete (memfile);
00216 
00217           return NULL;  /* PyList_Append Sets the exception.  */
00218         }
00219 
00220       TRY_CATCH (except, RETURN_MASK_ALL)
00221         {
00222           insn_len = gdb_print_insn (gdbarch, pc, memfile, NULL);
00223         }
00224       if (except.reason < 0)
00225         {
00226           Py_DECREF (result_list);
00227           ui_file_delete (memfile);
00228 
00229           gdbpy_convert_exception (except);
00230           return NULL;
00231         }
00232 
00233       as = ui_file_xstrdup (memfile, NULL);
00234       if (PyDict_SetItemString (insn_dict, "addr",
00235                                 gdb_py_long_from_ulongest (pc))
00236           || PyDict_SetItemString (insn_dict, "asm",
00237                                    PyString_FromString (*as ? as : "<unknown>"))
00238           || PyDict_SetItemString (insn_dict, "length",
00239                                    PyInt_FromLong (insn_len)))
00240         {
00241           Py_DECREF (result_list);
00242 
00243           ui_file_delete (memfile);
00244           xfree (as);
00245 
00246           return NULL;
00247         }
00248 
00249       pc += insn_len;
00250       i++;
00251       ui_file_delete (memfile);
00252       xfree (as);
00253     }
00254 
00255   return result_list;
00256 }
00257 
00258 /* Initializes the Architecture class in the gdb module.  */
00259 
00260 int
00261 gdbpy_initialize_arch (void)
00262 {
00263   arch_object_data = gdbarch_data_register_post_init (arch_object_data_init);
00264   arch_object_type.tp_new = PyType_GenericNew;
00265   if (PyType_Ready (&arch_object_type) < 0)
00266     return -1;
00267 
00268   return gdb_pymodule_addobject (gdb_module, "Architecture",
00269                                  (PyObject *) &arch_object_type);
00270 }
00271 
00272 static PyMethodDef arch_object_methods [] = {
00273   { "name", archpy_name, METH_NOARGS,
00274     "name () -> String.\n\
00275 Return the name of the architecture as a string value." },
00276   { "disassemble", (PyCFunction) archpy_disassemble,
00277     METH_VARARGS | METH_KEYWORDS,
00278     "disassemble (start_pc [, end_pc [, count]]) -> List.\n\
00279 Return a list of at most COUNT disassembled instructions from START_PC to\n\
00280 END_PC." },
00281   {NULL}  /* Sentinel */
00282 };
00283 
00284 static PyTypeObject arch_object_type = {
00285   PyVarObject_HEAD_INIT (NULL, 0)
00286   "gdb.Architecture",                 /* tp_name */
00287   sizeof (arch_object),               /* tp_basicsize */
00288   0,                                  /* tp_itemsize */
00289   0,                                  /* tp_dealloc */
00290   0,                                  /* tp_print */
00291   0,                                  /* tp_getattr */
00292   0,                                  /* tp_setattr */
00293   0,                                  /* tp_compare */
00294   0,                                  /* tp_repr */
00295   0,                                  /* tp_as_number */
00296   0,                                  /* tp_as_sequence */
00297   0,                                  /* tp_as_mapping */
00298   0,                                  /* tp_hash  */
00299   0,                                  /* tp_call */
00300   0,                                  /* tp_str */
00301   0,                                  /* tp_getattro */
00302   0,                                  /* tp_setattro */
00303   0,                                  /* tp_as_buffer */
00304   Py_TPFLAGS_DEFAULT,                 /* tp_flags */
00305   "GDB architecture object",          /* tp_doc */
00306   0,                                  /* tp_traverse */
00307   0,                                  /* tp_clear */
00308   0,                                  /* tp_richcompare */
00309   0,                                  /* tp_weaklistoffset */
00310   0,                                  /* tp_iter */
00311   0,                                  /* tp_iternext */
00312   arch_object_methods,                /* tp_methods */
00313   0,                                  /* tp_members */
00314   0,                                  /* tp_getset */
00315   0,                                  /* tp_base */
00316   0,                                  /* tp_dict */
00317   0,                                  /* tp_descr_get */
00318   0,                                  /* tp_descr_set */
00319   0,                                  /* tp_dictoffset */
00320   0,                                  /* tp_init */
00321   0,                                  /* tp_alloc */
00322 };
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines