Home | History | Annotate | Line # | Download | only in python
py-arch.c revision 1.1
      1  1.1  christos /* Python interface to architecture
      2  1.1  christos 
      3  1.1  christos    Copyright (C) 2013-2014 Free Software Foundation, Inc.
      4  1.1  christos 
      5  1.1  christos    This file is part of GDB.
      6  1.1  christos 
      7  1.1  christos    This program is free software; you can redistribute it and/or modify
      8  1.1  christos    it under the terms of the GNU General Public License as published by
      9  1.1  christos    the Free Software Foundation; either version 3 of the License, or
     10  1.1  christos    (at your option) any later version.
     11  1.1  christos 
     12  1.1  christos    This program is distributed in the hope that it will be useful,
     13  1.1  christos    but WITHOUT ANY WARRANTY; without even the implied warranty of
     14  1.1  christos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15  1.1  christos    GNU General Public License for more details.
     16  1.1  christos 
     17  1.1  christos    You should have received a copy of the GNU General Public License
     18  1.1  christos    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
     19  1.1  christos 
     20  1.1  christos #include "defs.h"
     21  1.1  christos #include "gdbarch.h"
     22  1.1  christos #include "arch-utils.h"
     23  1.1  christos #include "disasm.h"
     24  1.1  christos #include "python-internal.h"
     25  1.1  christos 
     26  1.1  christos typedef struct arch_object_type_object {
     27  1.1  christos   PyObject_HEAD
     28  1.1  christos   struct gdbarch *gdbarch;
     29  1.1  christos } arch_object;
     30  1.1  christos 
     31  1.1  christos static struct gdbarch_data *arch_object_data = NULL;
     32  1.1  christos 
     33  1.1  christos /* Require a valid Architecture.  */
     34  1.1  christos #define ARCHPY_REQUIRE_VALID(arch_obj, arch)			\
     35  1.1  christos   do {								\
     36  1.1  christos     arch = arch_object_to_gdbarch (arch_obj);			\
     37  1.1  christos     if (arch == NULL)						\
     38  1.1  christos       {								\
     39  1.1  christos 	PyErr_SetString (PyExc_RuntimeError,			\
     40  1.1  christos 			 _("Architecture is invalid."));	\
     41  1.1  christos 	return NULL;						\
     42  1.1  christos       }								\
     43  1.1  christos   } while (0)
     44  1.1  christos 
     45  1.1  christos static PyTypeObject arch_object_type
     46  1.1  christos     CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("arch_object");
     47  1.1  christos 
     48  1.1  christos /* Associates an arch_object with GDBARCH as gdbarch_data via the gdbarch
     49  1.1  christos    post init registration mechanism (gdbarch_data_register_post_init).  */
     50  1.1  christos 
     51  1.1  christos static void *
     52  1.1  christos arch_object_data_init (struct gdbarch *gdbarch)
     53  1.1  christos {
     54  1.1  christos   arch_object *arch_obj = PyObject_New (arch_object, &arch_object_type);
     55  1.1  christos 
     56  1.1  christos   if (arch_obj == NULL)
     57  1.1  christos     return NULL;
     58  1.1  christos 
     59  1.1  christos   arch_obj->gdbarch = gdbarch;
     60  1.1  christos 
     61  1.1  christos   return (void *) arch_obj;
     62  1.1  christos }
     63  1.1  christos 
     64  1.1  christos /* Returns the struct gdbarch value corresponding to the given Python
     65  1.1  christos    architecture object OBJ.  */
     66  1.1  christos 
     67  1.1  christos struct gdbarch *
     68  1.1  christos arch_object_to_gdbarch (PyObject *obj)
     69  1.1  christos {
     70  1.1  christos   arch_object *py_arch = (arch_object *) obj;
     71  1.1  christos 
     72  1.1  christos   return py_arch->gdbarch;
     73  1.1  christos }
     74  1.1  christos 
     75  1.1  christos /* Returns the Python architecture object corresponding to GDBARCH.
     76  1.1  christos    Returns a new reference to the arch_object associated as data with
     77  1.1  christos    GDBARCH.  */
     78  1.1  christos 
     79  1.1  christos PyObject *
     80  1.1  christos gdbarch_to_arch_object (struct gdbarch *gdbarch)
     81  1.1  christos {
     82  1.1  christos   PyObject *new_ref = (PyObject *) gdbarch_data (gdbarch, arch_object_data);
     83  1.1  christos 
     84  1.1  christos   /* new_ref could be NULL if registration of arch_object with GDBARCH failed
     85  1.1  christos      in arch_object_data_init.  */
     86  1.1  christos   Py_XINCREF (new_ref);
     87  1.1  christos 
     88  1.1  christos   return new_ref;
     89  1.1  christos }
     90  1.1  christos 
     91  1.1  christos /* Implementation of gdb.Architecture.name (self) -> String.
     92  1.1  christos    Returns the name of the architecture as a string value.  */
     93  1.1  christos 
     94  1.1  christos static PyObject *
     95  1.1  christos archpy_name (PyObject *self, PyObject *args)
     96  1.1  christos {
     97  1.1  christos   struct gdbarch *gdbarch = NULL;
     98  1.1  christos   const char *name;
     99  1.1  christos   PyObject *py_name;
    100  1.1  christos 
    101  1.1  christos   ARCHPY_REQUIRE_VALID (self, gdbarch);
    102  1.1  christos 
    103  1.1  christos   name = (gdbarch_bfd_arch_info (gdbarch))->printable_name;
    104  1.1  christos   py_name = PyString_FromString (name);
    105  1.1  christos 
    106  1.1  christos   return py_name;
    107  1.1  christos }
    108  1.1  christos 
    109  1.1  christos /* Implementation of
    110  1.1  christos    gdb.Architecture.disassemble (self, start_pc [, end_pc [,count]]) -> List.
    111  1.1  christos    Returns a list of instructions in a memory address range.  Each instruction
    112  1.1  christos    in the list is a Python dict object.
    113  1.1  christos */
    114  1.1  christos 
    115  1.1  christos static PyObject *
    116  1.1  christos archpy_disassemble (PyObject *self, PyObject *args, PyObject *kw)
    117  1.1  christos {
    118  1.1  christos   static char *keywords[] = { "start_pc", "end_pc", "count", NULL };
    119  1.1  christos   CORE_ADDR start, end = 0;
    120  1.1  christos   CORE_ADDR pc;
    121  1.1  christos   gdb_py_ulongest start_temp;
    122  1.1  christos   long count = 0, i;
    123  1.1  christos   PyObject *result_list, *end_obj = NULL, *count_obj = NULL;
    124  1.1  christos   struct gdbarch *gdbarch = NULL;
    125  1.1  christos 
    126  1.1  christos   ARCHPY_REQUIRE_VALID (self, gdbarch);
    127  1.1  christos 
    128  1.1  christos   if (!PyArg_ParseTupleAndKeywords (args, kw, GDB_PY_LLU_ARG "|OO", keywords,
    129  1.1  christos                                     &start_temp, &end_obj, &count_obj))
    130  1.1  christos     return NULL;
    131  1.1  christos 
    132  1.1  christos   start = start_temp;
    133  1.1  christos   if (end_obj)
    134  1.1  christos     {
    135  1.1  christos       /* Make a long logic check first.  In Python 3.x, internally,
    136  1.1  christos 	 all integers are represented as longs.  In Python 2.x, there
    137  1.1  christos 	 is still a differentiation internally between a PyInt and a
    138  1.1  christos 	 PyLong.  Explicitly do this long check conversion first. In
    139  1.1  christos 	 GDB, for Python 3.x, we #ifdef PyInt = PyLong.  This check has
    140  1.1  christos 	 to be done first to ensure we do not lose information in the
    141  1.1  christos 	 conversion process.  */
    142  1.1  christos       if (PyLong_Check (end_obj))
    143  1.1  christos         end = PyLong_AsUnsignedLongLong (end_obj);
    144  1.1  christos       else if (PyInt_Check (end_obj))
    145  1.1  christos         /* If the end_pc value is specified without a trailing 'L', end_obj will
    146  1.1  christos            be an integer and not a long integer.  */
    147  1.1  christos         end = PyInt_AsLong (end_obj);
    148  1.1  christos       else
    149  1.1  christos         {
    150  1.1  christos           Py_DECREF (end_obj);
    151  1.1  christos           Py_XDECREF (count_obj);
    152  1.1  christos           PyErr_SetString (PyExc_TypeError,
    153  1.1  christos                            _("Argument 'end_pc' should be a (long) integer."));
    154  1.1  christos 
    155  1.1  christos           return NULL;
    156  1.1  christos         }
    157  1.1  christos 
    158  1.1  christos       if (end < start)
    159  1.1  christos         {
    160  1.1  christos           Py_DECREF (end_obj);
    161  1.1  christos           Py_XDECREF (count_obj);
    162  1.1  christos           PyErr_SetString (PyExc_ValueError,
    163  1.1  christos                            _("Argument 'end_pc' should be greater than or "
    164  1.1  christos                              "equal to the argument 'start_pc'."));
    165  1.1  christos 
    166  1.1  christos           return NULL;
    167  1.1  christos         }
    168  1.1  christos     }
    169  1.1  christos   if (count_obj)
    170  1.1  christos     {
    171  1.1  christos       count = PyInt_AsLong (count_obj);
    172  1.1  christos       if (PyErr_Occurred () || count < 0)
    173  1.1  christos         {
    174  1.1  christos           Py_DECREF (count_obj);
    175  1.1  christos           Py_XDECREF (end_obj);
    176  1.1  christos           PyErr_SetString (PyExc_TypeError,
    177  1.1  christos                            _("Argument 'count' should be an non-negative "
    178  1.1  christos                              "integer."));
    179  1.1  christos 
    180  1.1  christos           return NULL;
    181  1.1  christos         }
    182  1.1  christos     }
    183  1.1  christos 
    184  1.1  christos   result_list = PyList_New (0);
    185  1.1  christos   if (result_list == NULL)
    186  1.1  christos     return NULL;
    187  1.1  christos 
    188  1.1  christos   for (pc = start, i = 0;
    189  1.1  christos        /* All args are specified.  */
    190  1.1  christos        (end_obj && count_obj && pc <= end && i < count)
    191  1.1  christos        /* end_pc is specified, but no count.  */
    192  1.1  christos        || (end_obj && count_obj == NULL && pc <= end)
    193  1.1  christos        /* end_pc is not specified, but a count is.  */
    194  1.1  christos        || (end_obj == NULL && count_obj && i < count)
    195  1.1  christos        /* Both end_pc and count are not specified.  */
    196  1.1  christos        || (end_obj == NULL && count_obj == NULL && pc == start);)
    197  1.1  christos     {
    198  1.1  christos       int insn_len = 0;
    199  1.1  christos       char *as = NULL;
    200  1.1  christos       struct ui_file *memfile = mem_fileopen ();
    201  1.1  christos       PyObject *insn_dict = PyDict_New ();
    202  1.1  christos       volatile struct gdb_exception except;
    203  1.1  christos 
    204  1.1  christos       if (insn_dict == NULL)
    205  1.1  christos         {
    206  1.1  christos           Py_DECREF (result_list);
    207  1.1  christos           ui_file_delete (memfile);
    208  1.1  christos 
    209  1.1  christos           return NULL;
    210  1.1  christos         }
    211  1.1  christos       if (PyList_Append (result_list, insn_dict))
    212  1.1  christos         {
    213  1.1  christos           Py_DECREF (result_list);
    214  1.1  christos           Py_DECREF (insn_dict);
    215  1.1  christos           ui_file_delete (memfile);
    216  1.1  christos 
    217  1.1  christos           return NULL;  /* PyList_Append Sets the exception.  */
    218  1.1  christos         }
    219  1.1  christos 
    220  1.1  christos       TRY_CATCH (except, RETURN_MASK_ALL)
    221  1.1  christos         {
    222  1.1  christos           insn_len = gdb_print_insn (gdbarch, pc, memfile, NULL);
    223  1.1  christos         }
    224  1.1  christos       if (except.reason < 0)
    225  1.1  christos         {
    226  1.1  christos           Py_DECREF (result_list);
    227  1.1  christos           ui_file_delete (memfile);
    228  1.1  christos 
    229  1.1  christos 	  gdbpy_convert_exception (except);
    230  1.1  christos 	  return NULL;
    231  1.1  christos         }
    232  1.1  christos 
    233  1.1  christos       as = ui_file_xstrdup (memfile, NULL);
    234  1.1  christos       if (PyDict_SetItemString (insn_dict, "addr",
    235  1.1  christos                                 gdb_py_long_from_ulongest (pc))
    236  1.1  christos           || PyDict_SetItemString (insn_dict, "asm",
    237  1.1  christos                                    PyString_FromString (*as ? as : "<unknown>"))
    238  1.1  christos           || PyDict_SetItemString (insn_dict, "length",
    239  1.1  christos                                    PyInt_FromLong (insn_len)))
    240  1.1  christos         {
    241  1.1  christos           Py_DECREF (result_list);
    242  1.1  christos 
    243  1.1  christos           ui_file_delete (memfile);
    244  1.1  christos           xfree (as);
    245  1.1  christos 
    246  1.1  christos           return NULL;
    247  1.1  christos         }
    248  1.1  christos 
    249  1.1  christos       pc += insn_len;
    250  1.1  christos       i++;
    251  1.1  christos       ui_file_delete (memfile);
    252  1.1  christos       xfree (as);
    253  1.1  christos     }
    254  1.1  christos 
    255  1.1  christos   return result_list;
    256  1.1  christos }
    257  1.1  christos 
    258  1.1  christos /* Initializes the Architecture class in the gdb module.  */
    259  1.1  christos 
    260  1.1  christos int
    261  1.1  christos gdbpy_initialize_arch (void)
    262  1.1  christos {
    263  1.1  christos   arch_object_data = gdbarch_data_register_post_init (arch_object_data_init);
    264  1.1  christos   arch_object_type.tp_new = PyType_GenericNew;
    265  1.1  christos   if (PyType_Ready (&arch_object_type) < 0)
    266  1.1  christos     return -1;
    267  1.1  christos 
    268  1.1  christos   return gdb_pymodule_addobject (gdb_module, "Architecture",
    269  1.1  christos 				 (PyObject *) &arch_object_type);
    270  1.1  christos }
    271  1.1  christos 
    272  1.1  christos static PyMethodDef arch_object_methods [] = {
    273  1.1  christos   { "name", archpy_name, METH_NOARGS,
    274  1.1  christos     "name () -> String.\n\
    275  1.1  christos Return the name of the architecture as a string value." },
    276  1.1  christos   { "disassemble", (PyCFunction) archpy_disassemble,
    277  1.1  christos     METH_VARARGS | METH_KEYWORDS,
    278  1.1  christos     "disassemble (start_pc [, end_pc [, count]]) -> List.\n\
    279  1.1  christos Return a list of at most COUNT disassembled instructions from START_PC to\n\
    280  1.1  christos END_PC." },
    281  1.1  christos   {NULL}  /* Sentinel */
    282  1.1  christos };
    283  1.1  christos 
    284  1.1  christos static PyTypeObject arch_object_type = {
    285  1.1  christos   PyVarObject_HEAD_INIT (NULL, 0)
    286  1.1  christos   "gdb.Architecture",                 /* tp_name */
    287  1.1  christos   sizeof (arch_object),               /* tp_basicsize */
    288  1.1  christos   0,                                  /* tp_itemsize */
    289  1.1  christos   0,                                  /* tp_dealloc */
    290  1.1  christos   0,                                  /* tp_print */
    291  1.1  christos   0,                                  /* tp_getattr */
    292  1.1  christos   0,                                  /* tp_setattr */
    293  1.1  christos   0,                                  /* tp_compare */
    294  1.1  christos   0,                                  /* tp_repr */
    295  1.1  christos   0,                                  /* tp_as_number */
    296  1.1  christos   0,                                  /* tp_as_sequence */
    297  1.1  christos   0,                                  /* tp_as_mapping */
    298  1.1  christos   0,                                  /* tp_hash  */
    299  1.1  christos   0,                                  /* tp_call */
    300  1.1  christos   0,                                  /* tp_str */
    301  1.1  christos   0,                                  /* tp_getattro */
    302  1.1  christos   0,                                  /* tp_setattro */
    303  1.1  christos   0,                                  /* tp_as_buffer */
    304  1.1  christos   Py_TPFLAGS_DEFAULT,                 /* tp_flags */
    305  1.1  christos   "GDB architecture object",          /* tp_doc */
    306  1.1  christos   0,                                  /* tp_traverse */
    307  1.1  christos   0,                                  /* tp_clear */
    308  1.1  christos   0,                                  /* tp_richcompare */
    309  1.1  christos   0,                                  /* tp_weaklistoffset */
    310  1.1  christos   0,                                  /* tp_iter */
    311  1.1  christos   0,                                  /* tp_iternext */
    312  1.1  christos   arch_object_methods,                /* tp_methods */
    313  1.1  christos   0,                                  /* tp_members */
    314  1.1  christos   0,                                  /* tp_getset */
    315  1.1  christos   0,                                  /* tp_base */
    316  1.1  christos   0,                                  /* tp_dict */
    317  1.1  christos   0,                                  /* tp_descr_get */
    318  1.1  christos   0,                                  /* tp_descr_set */
    319  1.1  christos   0,                                  /* tp_dictoffset */
    320  1.1  christos   0,                                  /* tp_init */
    321  1.1  christos   0,                                  /* tp_alloc */
    322  1.1  christos };
    323