Home | History | Annotate | Line # | Download | only in python
py-inferior.c revision 1.3
      1  1.1  christos /* Python interface to inferiors.
      2  1.1  christos 
      3  1.3  christos    Copyright (C) 2009-2015 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 "gdbcore.h"
     22  1.1  christos #include "gdbthread.h"
     23  1.1  christos #include "inferior.h"
     24  1.1  christos #include "objfiles.h"
     25  1.1  christos #include "observer.h"
     26  1.1  christos #include "python-internal.h"
     27  1.1  christos #include "arch-utils.h"
     28  1.1  christos #include "language.h"
     29  1.1  christos #include "gdb_signals.h"
     30  1.1  christos #include "py-event.h"
     31  1.1  christos #include "py-stopevent.h"
     32  1.1  christos 
     33  1.1  christos struct threadlist_entry {
     34  1.1  christos   thread_object *thread_obj;
     35  1.1  christos   struct threadlist_entry *next;
     36  1.1  christos };
     37  1.1  christos 
     38  1.1  christos typedef struct
     39  1.1  christos {
     40  1.1  christos   PyObject_HEAD
     41  1.1  christos 
     42  1.1  christos   /* The inferior we represent.  */
     43  1.1  christos   struct inferior *inferior;
     44  1.1  christos 
     45  1.1  christos   /* thread_object instances under this inferior.  This list owns a
     46  1.1  christos      reference to each object it contains.  */
     47  1.1  christos   struct threadlist_entry *threads;
     48  1.1  christos 
     49  1.1  christos   /* Number of threads in the list.  */
     50  1.1  christos   int nthreads;
     51  1.1  christos } inferior_object;
     52  1.1  christos 
     53  1.1  christos static PyTypeObject inferior_object_type
     54  1.1  christos     CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("inferior_object");
     55  1.1  christos 
     56  1.1  christos static const struct inferior_data *infpy_inf_data_key;
     57  1.1  christos 
     58  1.1  christos typedef struct {
     59  1.1  christos   PyObject_HEAD
     60  1.1  christos   void *buffer;
     61  1.1  christos 
     62  1.1  christos   /* These are kept just for mbpy_str.  */
     63  1.1  christos   CORE_ADDR addr;
     64  1.1  christos   CORE_ADDR length;
     65  1.1  christos } membuf_object;
     66  1.1  christos 
     67  1.1  christos static PyTypeObject membuf_object_type
     68  1.1  christos     CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("membuf_object");
     69  1.1  christos 
     70  1.1  christos /* Require that INFERIOR be a valid inferior ID.  */
     71  1.1  christos #define INFPY_REQUIRE_VALID(Inferior)				\
     72  1.1  christos   do {								\
     73  1.1  christos     if (!Inferior->inferior)					\
     74  1.1  christos       {								\
     75  1.1  christos 	PyErr_SetString (PyExc_RuntimeError,			\
     76  1.1  christos 			 _("Inferior no longer exists."));	\
     77  1.1  christos 	return NULL;						\
     78  1.1  christos       }								\
     79  1.1  christos   } while (0)
     80  1.1  christos 
     81  1.1  christos static void
     82  1.1  christos python_on_normal_stop (struct bpstats *bs, int print_frame)
     83  1.1  christos {
     84  1.1  christos   struct cleanup *cleanup;
     85  1.1  christos   enum gdb_signal stop_signal;
     86  1.1  christos 
     87  1.1  christos   if (!gdb_python_initialized)
     88  1.1  christos     return;
     89  1.1  christos 
     90  1.1  christos   if (!find_thread_ptid (inferior_ptid))
     91  1.1  christos       return;
     92  1.1  christos 
     93  1.1  christos   stop_signal = inferior_thread ()->suspend.stop_signal;
     94  1.1  christos 
     95  1.1  christos   cleanup = ensure_python_env (get_current_arch (), current_language);
     96  1.1  christos 
     97  1.1  christos   if (emit_stop_event (bs, stop_signal) < 0)
     98  1.1  christos     gdbpy_print_stack ();
     99  1.1  christos 
    100  1.1  christos   do_cleanups (cleanup);
    101  1.1  christos }
    102  1.1  christos 
    103  1.1  christos static void
    104  1.1  christos python_on_resume (ptid_t ptid)
    105  1.1  christos {
    106  1.1  christos   struct cleanup *cleanup;
    107  1.1  christos 
    108  1.1  christos   if (!gdb_python_initialized)
    109  1.1  christos     return;
    110  1.1  christos 
    111  1.1  christos   cleanup = ensure_python_env (target_gdbarch (), current_language);
    112  1.1  christos 
    113  1.1  christos   if (emit_continue_event (ptid) < 0)
    114  1.1  christos     gdbpy_print_stack ();
    115  1.1  christos 
    116  1.1  christos   do_cleanups (cleanup);
    117  1.1  christos }
    118  1.1  christos 
    119  1.3  christos /* Callback, registered as an observer, that notifies Python listeners
    120  1.3  christos    when an inferior function call is about to be made. */
    121  1.3  christos 
    122  1.3  christos static void
    123  1.3  christos python_on_inferior_call_pre (ptid_t thread, CORE_ADDR address)
    124  1.3  christos {
    125  1.3  christos   struct cleanup *cleanup;
    126  1.3  christos 
    127  1.3  christos   cleanup = ensure_python_env (target_gdbarch (), current_language);
    128  1.3  christos 
    129  1.3  christos   if (emit_inferior_call_event (INFERIOR_CALL_PRE, thread, address) < 0)
    130  1.3  christos     gdbpy_print_stack ();
    131  1.3  christos 
    132  1.3  christos   do_cleanups (cleanup);
    133  1.3  christos }
    134  1.3  christos 
    135  1.3  christos /* Callback, registered as an observer, that notifies Python listeners
    136  1.3  christos    when an inferior function call has completed. */
    137  1.3  christos 
    138  1.3  christos static void
    139  1.3  christos python_on_inferior_call_post (ptid_t thread, CORE_ADDR address)
    140  1.3  christos {
    141  1.3  christos   struct cleanup *cleanup;
    142  1.3  christos 
    143  1.3  christos   cleanup = ensure_python_env (target_gdbarch (), current_language);
    144  1.3  christos 
    145  1.3  christos   if (emit_inferior_call_event (INFERIOR_CALL_POST, thread, address) < 0)
    146  1.3  christos     gdbpy_print_stack ();
    147  1.3  christos 
    148  1.3  christos   do_cleanups (cleanup);
    149  1.3  christos }
    150  1.3  christos 
    151  1.3  christos /* Callback, registered as an observer, that notifies Python listeners
    152  1.3  christos    when a part of memory has been modified by user action (eg via a
    153  1.3  christos    'set' command). */
    154  1.3  christos 
    155  1.3  christos static void
    156  1.3  christos python_on_memory_change (struct inferior *inferior, CORE_ADDR addr, ssize_t len, const bfd_byte *data)
    157  1.3  christos {
    158  1.3  christos   struct cleanup *cleanup;
    159  1.3  christos 
    160  1.3  christos   cleanup = ensure_python_env (target_gdbarch (), current_language);
    161  1.3  christos 
    162  1.3  christos   if (emit_memory_changed_event (addr, len) < 0)
    163  1.3  christos     gdbpy_print_stack ();
    164  1.3  christos 
    165  1.3  christos   do_cleanups (cleanup);
    166  1.3  christos }
    167  1.3  christos 
    168  1.3  christos /* Callback, registered as an observer, that notifies Python listeners
    169  1.3  christos    when a register has been modified by user action (eg via a 'set'
    170  1.3  christos    command). */
    171  1.3  christos 
    172  1.3  christos static void
    173  1.3  christos python_on_register_change (struct frame_info *frame, int regnum)
    174  1.3  christos {
    175  1.3  christos   struct cleanup *cleanup;
    176  1.3  christos 
    177  1.3  christos   cleanup = ensure_python_env (target_gdbarch (), current_language);
    178  1.3  christos 
    179  1.3  christos   if (emit_register_changed_event (frame, regnum) < 0)
    180  1.3  christos     gdbpy_print_stack ();
    181  1.3  christos 
    182  1.3  christos   do_cleanups (cleanup);
    183  1.3  christos }
    184  1.3  christos 
    185  1.1  christos static void
    186  1.1  christos python_inferior_exit (struct inferior *inf)
    187  1.1  christos {
    188  1.1  christos   struct cleanup *cleanup;
    189  1.1  christos   const LONGEST *exit_code = NULL;
    190  1.1  christos 
    191  1.1  christos   if (!gdb_python_initialized)
    192  1.1  christos     return;
    193  1.1  christos 
    194  1.1  christos   cleanup = ensure_python_env (target_gdbarch (), current_language);
    195  1.1  christos 
    196  1.1  christos   if (inf->has_exit_code)
    197  1.1  christos     exit_code = &inf->exit_code;
    198  1.1  christos 
    199  1.1  christos   if (emit_exited_event (exit_code, inf) < 0)
    200  1.1  christos     gdbpy_print_stack ();
    201  1.1  christos 
    202  1.1  christos   do_cleanups (cleanup);
    203  1.1  christos }
    204  1.1  christos 
    205  1.1  christos /* Callback used to notify Python listeners about new objfiles loaded in the
    206  1.3  christos    inferior.  OBJFILE may be NULL which means that the objfile list has been
    207  1.3  christos    cleared (emptied).  */
    208  1.1  christos 
    209  1.1  christos static void
    210  1.1  christos python_new_objfile (struct objfile *objfile)
    211  1.1  christos {
    212  1.1  christos   struct cleanup *cleanup;
    213  1.1  christos 
    214  1.1  christos   if (!gdb_python_initialized)
    215  1.1  christos     return;
    216  1.1  christos 
    217  1.3  christos   cleanup = ensure_python_env (objfile != NULL
    218  1.3  christos 			       ? get_objfile_arch (objfile)
    219  1.3  christos 			       : target_gdbarch (),
    220  1.3  christos 			       current_language);
    221  1.1  christos 
    222  1.3  christos   if (objfile == NULL)
    223  1.3  christos     {
    224  1.3  christos       if (emit_clear_objfiles_event () < 0)
    225  1.3  christos 	gdbpy_print_stack ();
    226  1.3  christos     }
    227  1.3  christos   else
    228  1.3  christos     {
    229  1.3  christos       if (emit_new_objfile_event (objfile) < 0)
    230  1.3  christos 	gdbpy_print_stack ();
    231  1.3  christos     }
    232  1.1  christos 
    233  1.1  christos   do_cleanups (cleanup);
    234  1.1  christos }
    235  1.1  christos 
    236  1.1  christos /* Return a reference to the Python object of type Inferior
    237  1.1  christos    representing INFERIOR.  If the object has already been created,
    238  1.1  christos    return it and increment the reference count,  otherwise, create it.
    239  1.1  christos    Return NULL on failure.  */
    240  1.1  christos PyObject *
    241  1.1  christos inferior_to_inferior_object (struct inferior *inferior)
    242  1.1  christos {
    243  1.1  christos   inferior_object *inf_obj;
    244  1.1  christos 
    245  1.1  christos   inf_obj = inferior_data (inferior, infpy_inf_data_key);
    246  1.1  christos   if (!inf_obj)
    247  1.1  christos     {
    248  1.1  christos       inf_obj = PyObject_New (inferior_object, &inferior_object_type);
    249  1.1  christos       if (!inf_obj)
    250  1.1  christos 	  return NULL;
    251  1.1  christos 
    252  1.1  christos       inf_obj->inferior = inferior;
    253  1.1  christos       inf_obj->threads = NULL;
    254  1.1  christos       inf_obj->nthreads = 0;
    255  1.1  christos 
    256  1.1  christos       set_inferior_data (inferior, infpy_inf_data_key, inf_obj);
    257  1.1  christos 
    258  1.1  christos     }
    259  1.1  christos   else
    260  1.1  christos     Py_INCREF ((PyObject *)inf_obj);
    261  1.1  christos 
    262  1.1  christos   return (PyObject *) inf_obj;
    263  1.1  christos }
    264  1.1  christos 
    265  1.1  christos /* Finds the Python Inferior object for the given PID.  Returns a
    266  1.1  christos    reference, or NULL if PID does not match any inferior object. */
    267  1.1  christos 
    268  1.1  christos PyObject *
    269  1.1  christos find_inferior_object (int pid)
    270  1.1  christos {
    271  1.1  christos   struct inferior *inf = find_inferior_pid (pid);
    272  1.1  christos 
    273  1.1  christos   if (inf)
    274  1.1  christos     return inferior_to_inferior_object (inf);
    275  1.1  christos 
    276  1.1  christos   return NULL;
    277  1.1  christos }
    278  1.1  christos 
    279  1.1  christos thread_object *
    280  1.1  christos find_thread_object (ptid_t ptid)
    281  1.1  christos {
    282  1.1  christos   int pid;
    283  1.1  christos   struct threadlist_entry *thread;
    284  1.1  christos   PyObject *inf_obj;
    285  1.1  christos   thread_object *found = NULL;
    286  1.1  christos 
    287  1.1  christos   pid = ptid_get_pid (ptid);
    288  1.1  christos   if (pid == 0)
    289  1.1  christos     return NULL;
    290  1.1  christos 
    291  1.1  christos   inf_obj = find_inferior_object (pid);
    292  1.1  christos 
    293  1.1  christos   if (! inf_obj)
    294  1.1  christos     return NULL;
    295  1.1  christos 
    296  1.1  christos   for (thread = ((inferior_object *)inf_obj)->threads; thread;
    297  1.1  christos        thread = thread->next)
    298  1.1  christos     if (ptid_equal (thread->thread_obj->thread->ptid, ptid))
    299  1.1  christos       {
    300  1.1  christos 	found = thread->thread_obj;
    301  1.1  christos 	break;
    302  1.1  christos       }
    303  1.1  christos 
    304  1.1  christos   Py_DECREF (inf_obj);
    305  1.1  christos 
    306  1.1  christos   if (found)
    307  1.1  christos     return found;
    308  1.1  christos 
    309  1.1  christos   return NULL;
    310  1.1  christos }
    311  1.1  christos 
    312  1.1  christos static void
    313  1.1  christos add_thread_object (struct thread_info *tp)
    314  1.1  christos {
    315  1.1  christos   struct cleanup *cleanup;
    316  1.1  christos   thread_object *thread_obj;
    317  1.1  christos   inferior_object *inf_obj;
    318  1.1  christos   struct threadlist_entry *entry;
    319  1.1  christos 
    320  1.1  christos   if (!gdb_python_initialized)
    321  1.1  christos     return;
    322  1.1  christos 
    323  1.1  christos   cleanup = ensure_python_env (python_gdbarch, python_language);
    324  1.1  christos 
    325  1.1  christos   thread_obj = create_thread_object (tp);
    326  1.1  christos   if (!thread_obj)
    327  1.1  christos     {
    328  1.1  christos       gdbpy_print_stack ();
    329  1.1  christos       do_cleanups (cleanup);
    330  1.1  christos       return;
    331  1.1  christos     }
    332  1.1  christos 
    333  1.1  christos   inf_obj = (inferior_object *) thread_obj->inf_obj;
    334  1.1  christos 
    335  1.1  christos   entry = xmalloc (sizeof (struct threadlist_entry));
    336  1.1  christos   entry->thread_obj = thread_obj;
    337  1.1  christos   entry->next = inf_obj->threads;
    338  1.1  christos 
    339  1.1  christos   inf_obj->threads = entry;
    340  1.1  christos   inf_obj->nthreads++;
    341  1.1  christos 
    342  1.1  christos   do_cleanups (cleanup);
    343  1.1  christos }
    344  1.1  christos 
    345  1.1  christos static void
    346  1.1  christos delete_thread_object (struct thread_info *tp, int ignore)
    347  1.1  christos {
    348  1.1  christos   struct cleanup *cleanup;
    349  1.1  christos   inferior_object *inf_obj;
    350  1.1  christos   struct threadlist_entry **entry, *tmp;
    351  1.1  christos 
    352  1.1  christos   if (!gdb_python_initialized)
    353  1.1  christos     return;
    354  1.1  christos 
    355  1.1  christos   cleanup = ensure_python_env (python_gdbarch, python_language);
    356  1.1  christos 
    357  1.1  christos   inf_obj
    358  1.1  christos     = (inferior_object *) find_inferior_object (ptid_get_pid (tp->ptid));
    359  1.1  christos   if (!inf_obj)
    360  1.1  christos     {
    361  1.1  christos       do_cleanups (cleanup);
    362  1.1  christos       return;
    363  1.1  christos     }
    364  1.1  christos 
    365  1.1  christos   /* Find thread entry in its inferior's thread_list.  */
    366  1.1  christos   for (entry = &inf_obj->threads; *entry != NULL; entry =
    367  1.1  christos 	 &(*entry)->next)
    368  1.1  christos     if ((*entry)->thread_obj->thread == tp)
    369  1.1  christos       break;
    370  1.1  christos 
    371  1.1  christos   if (!*entry)
    372  1.1  christos     {
    373  1.1  christos       Py_DECREF (inf_obj);
    374  1.1  christos       do_cleanups (cleanup);
    375  1.1  christos       return;
    376  1.1  christos     }
    377  1.1  christos 
    378  1.1  christos   tmp = *entry;
    379  1.1  christos   tmp->thread_obj->thread = NULL;
    380  1.1  christos 
    381  1.1  christos   *entry = (*entry)->next;
    382  1.1  christos   inf_obj->nthreads--;
    383  1.1  christos 
    384  1.1  christos   Py_DECREF (tmp->thread_obj);
    385  1.1  christos   Py_DECREF (inf_obj);
    386  1.1  christos   xfree (tmp);
    387  1.1  christos 
    388  1.1  christos   do_cleanups (cleanup);
    389  1.1  christos }
    390  1.1  christos 
    391  1.1  christos static PyObject *
    392  1.1  christos infpy_threads (PyObject *self, PyObject *args)
    393  1.1  christos {
    394  1.1  christos   int i;
    395  1.1  christos   struct threadlist_entry *entry;
    396  1.1  christos   inferior_object *inf_obj = (inferior_object *) self;
    397  1.1  christos   PyObject *tuple;
    398  1.1  christos   volatile struct gdb_exception except;
    399  1.1  christos 
    400  1.1  christos   INFPY_REQUIRE_VALID (inf_obj);
    401  1.1  christos 
    402  1.1  christos   TRY_CATCH (except, RETURN_MASK_ALL)
    403  1.1  christos     update_thread_list ();
    404  1.1  christos   GDB_PY_HANDLE_EXCEPTION (except);
    405  1.1  christos 
    406  1.1  christos   tuple = PyTuple_New (inf_obj->nthreads);
    407  1.1  christos   if (!tuple)
    408  1.1  christos     return NULL;
    409  1.1  christos 
    410  1.1  christos   for (i = 0, entry = inf_obj->threads; i < inf_obj->nthreads;
    411  1.1  christos        i++, entry = entry->next)
    412  1.1  christos     {
    413  1.1  christos       Py_INCREF (entry->thread_obj);
    414  1.1  christos       PyTuple_SET_ITEM (tuple, i, (PyObject *) entry->thread_obj);
    415  1.1  christos     }
    416  1.1  christos 
    417  1.1  christos   return tuple;
    418  1.1  christos }
    419  1.1  christos 
    420  1.1  christos static PyObject *
    421  1.1  christos infpy_get_num (PyObject *self, void *closure)
    422  1.1  christos {
    423  1.1  christos   inferior_object *inf = (inferior_object *) self;
    424  1.1  christos 
    425  1.1  christos   INFPY_REQUIRE_VALID (inf);
    426  1.1  christos 
    427  1.1  christos   return PyLong_FromLong (inf->inferior->num);
    428  1.1  christos }
    429  1.1  christos 
    430  1.1  christos static PyObject *
    431  1.1  christos infpy_get_pid (PyObject *self, void *closure)
    432  1.1  christos {
    433  1.1  christos   inferior_object *inf = (inferior_object *) self;
    434  1.1  christos 
    435  1.1  christos   INFPY_REQUIRE_VALID (inf);
    436  1.1  christos 
    437  1.1  christos   return PyLong_FromLong (inf->inferior->pid);
    438  1.1  christos }
    439  1.1  christos 
    440  1.1  christos static PyObject *
    441  1.1  christos infpy_get_was_attached (PyObject *self, void *closure)
    442  1.1  christos {
    443  1.1  christos   inferior_object *inf = (inferior_object *) self;
    444  1.1  christos 
    445  1.1  christos   INFPY_REQUIRE_VALID (inf);
    446  1.1  christos   if (inf->inferior->attach_flag)
    447  1.1  christos     Py_RETURN_TRUE;
    448  1.1  christos   Py_RETURN_FALSE;
    449  1.1  christos }
    450  1.1  christos 
    451  1.1  christos static int
    452  1.1  christos build_inferior_list (struct inferior *inf, void *arg)
    453  1.1  christos {
    454  1.1  christos   PyObject *list = arg;
    455  1.1  christos   PyObject *inferior = inferior_to_inferior_object (inf);
    456  1.1  christos   int success = 0;
    457  1.1  christos 
    458  1.1  christos   if (! inferior)
    459  1.1  christos     return 0;
    460  1.1  christos 
    461  1.1  christos   success = PyList_Append (list, inferior);
    462  1.1  christos   Py_DECREF (inferior);
    463  1.1  christos 
    464  1.1  christos   if (success)
    465  1.1  christos     return 1;
    466  1.1  christos 
    467  1.1  christos   return 0;
    468  1.1  christos }
    469  1.1  christos 
    470  1.1  christos /* Implementation of gdb.inferiors () -> (gdb.Inferior, ...).
    471  1.1  christos    Returns a tuple of all inferiors.  */
    472  1.1  christos PyObject *
    473  1.1  christos gdbpy_inferiors (PyObject *unused, PyObject *unused2)
    474  1.1  christos {
    475  1.1  christos   PyObject *list, *tuple;
    476  1.1  christos 
    477  1.1  christos   list = PyList_New (0);
    478  1.1  christos   if (!list)
    479  1.1  christos     return NULL;
    480  1.1  christos 
    481  1.1  christos   if (iterate_over_inferiors (build_inferior_list, list))
    482  1.1  christos     {
    483  1.1  christos       Py_DECREF (list);
    484  1.1  christos       return NULL;
    485  1.1  christos     }
    486  1.1  christos 
    487  1.1  christos   tuple = PyList_AsTuple (list);
    488  1.1  christos   Py_DECREF (list);
    489  1.1  christos 
    490  1.1  christos   return tuple;
    491  1.1  christos }
    492  1.1  christos 
    493  1.1  christos /* Membuf and memory manipulation.  */
    494  1.1  christos 
    495  1.1  christos /* Implementation of Inferior.read_memory (address, length).
    496  1.1  christos    Returns a Python buffer object with LENGTH bytes of the inferior's
    497  1.1  christos    memory at ADDRESS.  Both arguments are integers.  Returns NULL on error,
    498  1.1  christos    with a python exception set.  */
    499  1.1  christos static PyObject *
    500  1.1  christos infpy_read_memory (PyObject *self, PyObject *args, PyObject *kw)
    501  1.1  christos {
    502  1.1  christos   CORE_ADDR addr, length;
    503  1.1  christos   void *buffer = NULL;
    504  1.1  christos   membuf_object *membuf_obj;
    505  1.1  christos   PyObject *addr_obj, *length_obj, *result;
    506  1.1  christos   volatile struct gdb_exception except;
    507  1.1  christos   static char *keywords[] = { "address", "length", NULL };
    508  1.1  christos 
    509  1.1  christos   if (! PyArg_ParseTupleAndKeywords (args, kw, "OO", keywords,
    510  1.1  christos 				     &addr_obj, &length_obj))
    511  1.1  christos     return NULL;
    512  1.1  christos 
    513  1.1  christos   if (get_addr_from_python (addr_obj, &addr) < 0
    514  1.1  christos       || get_addr_from_python (length_obj, &length) < 0)
    515  1.1  christos     return NULL;
    516  1.1  christos 
    517  1.1  christos   TRY_CATCH (except, RETURN_MASK_ALL)
    518  1.1  christos     {
    519  1.1  christos       buffer = xmalloc (length);
    520  1.1  christos 
    521  1.1  christos       read_memory (addr, buffer, length);
    522  1.1  christos     }
    523  1.1  christos   if (except.reason < 0)
    524  1.1  christos     {
    525  1.1  christos       xfree (buffer);
    526  1.1  christos       GDB_PY_HANDLE_EXCEPTION (except);
    527  1.1  christos     }
    528  1.1  christos 
    529  1.1  christos   membuf_obj = PyObject_New (membuf_object, &membuf_object_type);
    530  1.1  christos   if (membuf_obj == NULL)
    531  1.1  christos     {
    532  1.1  christos       xfree (buffer);
    533  1.1  christos       return NULL;
    534  1.1  christos     }
    535  1.1  christos 
    536  1.1  christos   membuf_obj->buffer = buffer;
    537  1.1  christos   membuf_obj->addr = addr;
    538  1.1  christos   membuf_obj->length = length;
    539  1.1  christos 
    540  1.1  christos #ifdef IS_PY3K
    541  1.1  christos   result = PyMemoryView_FromObject ((PyObject *) membuf_obj);
    542  1.1  christos #else
    543  1.1  christos   result = PyBuffer_FromReadWriteObject ((PyObject *) membuf_obj, 0,
    544  1.1  christos 					 Py_END_OF_BUFFER);
    545  1.1  christos #endif
    546  1.1  christos   Py_DECREF (membuf_obj);
    547  1.1  christos 
    548  1.1  christos   return result;
    549  1.1  christos }
    550  1.1  christos 
    551  1.1  christos /* Implementation of Inferior.write_memory (address, buffer [, length]).
    552  1.1  christos    Writes the contents of BUFFER (a Python object supporting the read
    553  1.1  christos    buffer protocol) at ADDRESS in the inferior's memory.  Write LENGTH
    554  1.1  christos    bytes from BUFFER, or its entire contents if the argument is not
    555  1.1  christos    provided.  The function returns nothing.  Returns NULL on error, with
    556  1.1  christos    a python exception set.  */
    557  1.1  christos static PyObject *
    558  1.1  christos infpy_write_memory (PyObject *self, PyObject *args, PyObject *kw)
    559  1.1  christos {
    560  1.1  christos   Py_ssize_t buf_len;
    561  1.1  christos   const char *buffer;
    562  1.1  christos   CORE_ADDR addr, length;
    563  1.1  christos   PyObject *addr_obj, *length_obj = NULL;
    564  1.1  christos   volatile struct gdb_exception except;
    565  1.1  christos   static char *keywords[] = { "address", "buffer", "length", NULL };
    566  1.1  christos #ifdef IS_PY3K
    567  1.1  christos   Py_buffer pybuf;
    568  1.1  christos 
    569  1.1  christos   if (! PyArg_ParseTupleAndKeywords (args, kw, "Os*|O", keywords,
    570  1.1  christos 				     &addr_obj, &pybuf,
    571  1.1  christos 				     &length_obj))
    572  1.1  christos     return NULL;
    573  1.1  christos 
    574  1.1  christos   buffer = pybuf.buf;
    575  1.1  christos   buf_len = pybuf.len;
    576  1.1  christos #else
    577  1.1  christos   if (! PyArg_ParseTupleAndKeywords (args, kw, "Os#|O", keywords,
    578  1.1  christos 				     &addr_obj, &buffer, &buf_len,
    579  1.1  christos 				     &length_obj))
    580  1.1  christos     return NULL;
    581  1.1  christos #endif
    582  1.1  christos 
    583  1.1  christos   if (get_addr_from_python (addr_obj, &addr) < 0)
    584  1.1  christos     goto fail;
    585  1.1  christos 
    586  1.1  christos   if (!length_obj)
    587  1.1  christos     length = buf_len;
    588  1.1  christos   else if (get_addr_from_python (length_obj, &length) < 0)
    589  1.1  christos     goto fail;
    590  1.1  christos 
    591  1.1  christos   TRY_CATCH (except, RETURN_MASK_ALL)
    592  1.1  christos     {
    593  1.1  christos       write_memory_with_notification (addr, (gdb_byte *) buffer, length);
    594  1.1  christos     }
    595  1.1  christos #ifdef IS_PY3K
    596  1.1  christos   PyBuffer_Release (&pybuf);
    597  1.1  christos #endif
    598  1.1  christos   GDB_PY_HANDLE_EXCEPTION (except);
    599  1.1  christos 
    600  1.1  christos   Py_RETURN_NONE;
    601  1.1  christos 
    602  1.1  christos  fail:
    603  1.1  christos #ifdef IS_PY3K
    604  1.1  christos   PyBuffer_Release (&pybuf);
    605  1.1  christos #endif
    606  1.1  christos   return NULL;
    607  1.1  christos }
    608  1.1  christos 
    609  1.1  christos /* Destructor of Membuf objects.  */
    610  1.1  christos static void
    611  1.1  christos mbpy_dealloc (PyObject *self)
    612  1.1  christos {
    613  1.1  christos   xfree (((membuf_object *) self)->buffer);
    614  1.1  christos   Py_TYPE (self)->tp_free (self);
    615  1.1  christos }
    616  1.1  christos 
    617  1.1  christos /* Return a description of the Membuf object.  */
    618  1.1  christos static PyObject *
    619  1.1  christos mbpy_str (PyObject *self)
    620  1.1  christos {
    621  1.1  christos   membuf_object *membuf_obj = (membuf_object *) self;
    622  1.1  christos 
    623  1.1  christos   return PyString_FromFormat (_("Memory buffer for address %s, \
    624  1.1  christos which is %s bytes long."),
    625  1.1  christos 			      paddress (python_gdbarch, membuf_obj->addr),
    626  1.1  christos 			      pulongest (membuf_obj->length));
    627  1.1  christos }
    628  1.1  christos 
    629  1.1  christos #ifdef IS_PY3K
    630  1.1  christos 
    631  1.1  christos static int
    632  1.1  christos get_buffer (PyObject *self, Py_buffer *buf, int flags)
    633  1.1  christos {
    634  1.1  christos   membuf_object *membuf_obj = (membuf_object *) self;
    635  1.1  christos   int ret;
    636  1.1  christos 
    637  1.1  christos   ret = PyBuffer_FillInfo (buf, self, membuf_obj->buffer,
    638  1.1  christos 			   membuf_obj->length, 0,
    639  1.1  christos 			   PyBUF_CONTIG);
    640  1.1  christos   buf->format = "c";
    641  1.1  christos 
    642  1.1  christos   return ret;
    643  1.1  christos }
    644  1.1  christos 
    645  1.1  christos #else
    646  1.1  christos 
    647  1.1  christos static Py_ssize_t
    648  1.1  christos get_read_buffer (PyObject *self, Py_ssize_t segment, void **ptrptr)
    649  1.1  christos {
    650  1.1  christos   membuf_object *membuf_obj = (membuf_object *) self;
    651  1.1  christos 
    652  1.1  christos   if (segment)
    653  1.1  christos     {
    654  1.1  christos       PyErr_SetString (PyExc_SystemError,
    655  1.1  christos 		       _("The memory buffer supports only one segment."));
    656  1.1  christos       return -1;
    657  1.1  christos     }
    658  1.1  christos 
    659  1.1  christos   *ptrptr = membuf_obj->buffer;
    660  1.1  christos 
    661  1.1  christos   return membuf_obj->length;
    662  1.1  christos }
    663  1.1  christos 
    664  1.1  christos static Py_ssize_t
    665  1.1  christos get_write_buffer (PyObject *self, Py_ssize_t segment, void **ptrptr)
    666  1.1  christos {
    667  1.1  christos   return get_read_buffer (self, segment, ptrptr);
    668  1.1  christos }
    669  1.1  christos 
    670  1.1  christos static Py_ssize_t
    671  1.1  christos get_seg_count (PyObject *self, Py_ssize_t *lenp)
    672  1.1  christos {
    673  1.1  christos   if (lenp)
    674  1.1  christos     *lenp = ((membuf_object *) self)->length;
    675  1.1  christos 
    676  1.1  christos   return 1;
    677  1.1  christos }
    678  1.1  christos 
    679  1.1  christos static Py_ssize_t
    680  1.1  christos get_char_buffer (PyObject *self, Py_ssize_t segment, char **ptrptr)
    681  1.1  christos {
    682  1.1  christos   void *ptr = NULL;
    683  1.1  christos   Py_ssize_t ret;
    684  1.1  christos 
    685  1.1  christos   ret = get_read_buffer (self, segment, &ptr);
    686  1.1  christos   *ptrptr = (char *) ptr;
    687  1.1  christos 
    688  1.1  christos   return ret;
    689  1.1  christos }
    690  1.1  christos 
    691  1.1  christos #endif	/* IS_PY3K */
    692  1.1  christos 
    693  1.1  christos /* Implementation of
    694  1.1  christos    gdb.search_memory (address, length, pattern).  ADDRESS is the
    695  1.1  christos    address to start the search.  LENGTH specifies the scope of the
    696  1.1  christos    search from ADDRESS.  PATTERN is the pattern to search for (and
    697  1.1  christos    must be a Python object supporting the buffer protocol).
    698  1.1  christos    Returns a Python Long object holding the address where the pattern
    699  1.1  christos    was located, or if the pattern was not found, returns None.  Returns NULL
    700  1.1  christos    on error, with a python exception set.  */
    701  1.1  christos static PyObject *
    702  1.1  christos infpy_search_memory (PyObject *self, PyObject *args, PyObject *kw)
    703  1.1  christos {
    704  1.1  christos   CORE_ADDR start_addr, length;
    705  1.1  christos   static char *keywords[] = { "address", "length", "pattern", NULL };
    706  1.1  christos   PyObject *start_addr_obj, *length_obj;
    707  1.1  christos   volatile struct gdb_exception except;
    708  1.1  christos   Py_ssize_t pattern_size;
    709  1.1  christos   const void *buffer;
    710  1.1  christos   CORE_ADDR found_addr;
    711  1.1  christos   int found = 0;
    712  1.1  christos #ifdef IS_PY3K
    713  1.1  christos   Py_buffer pybuf;
    714  1.1  christos 
    715  1.1  christos   if (! PyArg_ParseTupleAndKeywords (args, kw, "OOs*", keywords,
    716  1.1  christos 				     &start_addr_obj, &length_obj,
    717  1.1  christos 				     &pybuf))
    718  1.1  christos     return NULL;
    719  1.1  christos 
    720  1.1  christos   buffer = pybuf.buf;
    721  1.1  christos   pattern_size = pybuf.len;
    722  1.1  christos #else
    723  1.1  christos   PyObject *pattern;
    724  1.1  christos 
    725  1.1  christos   if (! PyArg_ParseTupleAndKeywords (args, kw, "OOO", keywords,
    726  1.1  christos  				     &start_addr_obj, &length_obj,
    727  1.1  christos 				     &pattern))
    728  1.1  christos      return NULL;
    729  1.1  christos 
    730  1.1  christos   if (!PyObject_CheckReadBuffer (pattern))
    731  1.1  christos     {
    732  1.1  christos       PyErr_SetString (PyExc_RuntimeError,
    733  1.1  christos 		       _("The pattern is not a Python buffer."));
    734  1.1  christos 
    735  1.1  christos       return NULL;
    736  1.1  christos     }
    737  1.1  christos 
    738  1.1  christos   if (PyObject_AsReadBuffer (pattern, &buffer, &pattern_size) == -1)
    739  1.1  christos     return NULL;
    740  1.1  christos #endif
    741  1.1  christos 
    742  1.1  christos   if (get_addr_from_python (start_addr_obj, &start_addr) < 0)
    743  1.1  christos     goto fail;
    744  1.1  christos 
    745  1.1  christos   if (get_addr_from_python (length_obj, &length) < 0)
    746  1.1  christos     goto fail;
    747  1.1  christos 
    748  1.1  christos   if (!length)
    749  1.1  christos     {
    750  1.1  christos       PyErr_SetString (PyExc_ValueError,
    751  1.1  christos 		       _("Search range is empty."));
    752  1.1  christos       goto fail;
    753  1.1  christos     }
    754  1.1  christos   /* Watch for overflows.  */
    755  1.1  christos   else if (length > CORE_ADDR_MAX
    756  1.1  christos 	   || (start_addr + length - 1) < start_addr)
    757  1.1  christos     {
    758  1.1  christos       PyErr_SetString (PyExc_ValueError,
    759  1.1  christos 		       _("The search range is too large."));
    760  1.1  christos       goto fail;
    761  1.1  christos     }
    762  1.1  christos 
    763  1.1  christos   TRY_CATCH (except, RETURN_MASK_ALL)
    764  1.1  christos     {
    765  1.1  christos       found = target_search_memory (start_addr, length,
    766  1.1  christos 				    buffer, pattern_size,
    767  1.1  christos 				    &found_addr);
    768  1.1  christos     }
    769  1.1  christos #ifdef IS_PY3K
    770  1.1  christos   PyBuffer_Release (&pybuf);
    771  1.1  christos #endif
    772  1.1  christos   GDB_PY_HANDLE_EXCEPTION (except);
    773  1.1  christos 
    774  1.1  christos   if (found)
    775  1.1  christos     return PyLong_FromLong (found_addr);
    776  1.1  christos   else
    777  1.1  christos     Py_RETURN_NONE;
    778  1.1  christos 
    779  1.1  christos  fail:
    780  1.1  christos #ifdef IS_PY3K
    781  1.1  christos   PyBuffer_Release (&pybuf);
    782  1.1  christos #endif
    783  1.1  christos   return NULL;
    784  1.1  christos }
    785  1.1  christos 
    786  1.1  christos /* Implementation of gdb.Inferior.is_valid (self) -> Boolean.
    787  1.1  christos    Returns True if this inferior object still exists in GDB.  */
    788  1.1  christos 
    789  1.1  christos static PyObject *
    790  1.1  christos infpy_is_valid (PyObject *self, PyObject *args)
    791  1.1  christos {
    792  1.1  christos   inferior_object *inf = (inferior_object *) self;
    793  1.1  christos 
    794  1.1  christos   if (! inf->inferior)
    795  1.1  christos     Py_RETURN_FALSE;
    796  1.1  christos 
    797  1.1  christos   Py_RETURN_TRUE;
    798  1.1  christos }
    799  1.1  christos 
    800  1.1  christos static void
    801  1.1  christos infpy_dealloc (PyObject *obj)
    802  1.1  christos {
    803  1.1  christos   inferior_object *inf_obj = (inferior_object *) obj;
    804  1.1  christos   struct inferior *inf = inf_obj->inferior;
    805  1.1  christos 
    806  1.1  christos   if (! inf)
    807  1.1  christos     return;
    808  1.1  christos 
    809  1.1  christos   set_inferior_data (inf, infpy_inf_data_key, NULL);
    810  1.1  christos }
    811  1.1  christos 
    812  1.1  christos /* Clear the INFERIOR pointer in an Inferior object and clear the
    813  1.1  christos    thread list.  */
    814  1.1  christos static void
    815  1.1  christos py_free_inferior (struct inferior *inf, void *datum)
    816  1.1  christos {
    817  1.1  christos 
    818  1.1  christos   struct cleanup *cleanup;
    819  1.1  christos   inferior_object *inf_obj = datum;
    820  1.1  christos   struct threadlist_entry *th_entry, *th_tmp;
    821  1.1  christos 
    822  1.1  christos   if (!gdb_python_initialized)
    823  1.1  christos     return;
    824  1.1  christos 
    825  1.1  christos   cleanup = ensure_python_env (python_gdbarch, python_language);
    826  1.1  christos 
    827  1.1  christos   inf_obj->inferior = NULL;
    828  1.1  christos 
    829  1.1  christos   /* Deallocate threads list.  */
    830  1.1  christos   for (th_entry = inf_obj->threads; th_entry != NULL;)
    831  1.1  christos     {
    832  1.1  christos       Py_DECREF (th_entry->thread_obj);
    833  1.1  christos 
    834  1.1  christos       th_tmp = th_entry;
    835  1.1  christos       th_entry = th_entry->next;
    836  1.1  christos       xfree (th_tmp);
    837  1.1  christos     }
    838  1.1  christos 
    839  1.1  christos   inf_obj->nthreads = 0;
    840  1.1  christos 
    841  1.1  christos   Py_DECREF ((PyObject *) inf_obj);
    842  1.1  christos   do_cleanups (cleanup);
    843  1.1  christos }
    844  1.1  christos 
    845  1.1  christos /* Implementation of gdb.selected_inferior() -> gdb.Inferior.
    846  1.1  christos    Returns the current inferior object.  */
    847  1.1  christos 
    848  1.1  christos PyObject *
    849  1.1  christos gdbpy_selected_inferior (PyObject *self, PyObject *args)
    850  1.1  christos {
    851  1.1  christos   return inferior_to_inferior_object (current_inferior ());
    852  1.1  christos }
    853  1.1  christos 
    854  1.1  christos int
    855  1.1  christos gdbpy_initialize_inferior (void)
    856  1.1  christos {
    857  1.1  christos   if (PyType_Ready (&inferior_object_type) < 0)
    858  1.1  christos     return -1;
    859  1.1  christos 
    860  1.1  christos   if (gdb_pymodule_addobject (gdb_module, "Inferior",
    861  1.1  christos 			      (PyObject *) &inferior_object_type) < 0)
    862  1.1  christos     return -1;
    863  1.1  christos 
    864  1.1  christos   infpy_inf_data_key =
    865  1.1  christos     register_inferior_data_with_cleanup (NULL, py_free_inferior);
    866  1.1  christos 
    867  1.1  christos   observer_attach_new_thread (add_thread_object);
    868  1.1  christos   observer_attach_thread_exit (delete_thread_object);
    869  1.1  christos   observer_attach_normal_stop (python_on_normal_stop);
    870  1.1  christos   observer_attach_target_resumed (python_on_resume);
    871  1.3  christos   observer_attach_inferior_call_pre (python_on_inferior_call_pre);
    872  1.3  christos   observer_attach_inferior_call_post (python_on_inferior_call_post);
    873  1.3  christos   observer_attach_memory_changed (python_on_memory_change);
    874  1.3  christos   observer_attach_register_changed (python_on_register_change);
    875  1.1  christos   observer_attach_inferior_exit (python_inferior_exit);
    876  1.1  christos   observer_attach_new_objfile (python_new_objfile);
    877  1.1  christos 
    878  1.1  christos   membuf_object_type.tp_new = PyType_GenericNew;
    879  1.1  christos   if (PyType_Ready (&membuf_object_type) < 0)
    880  1.1  christos     return -1;
    881  1.1  christos 
    882  1.1  christos   return gdb_pymodule_addobject (gdb_module, "Membuf", (PyObject *)
    883  1.1  christos 				 &membuf_object_type);
    884  1.1  christos }
    885  1.1  christos 
    886  1.1  christos static PyGetSetDef inferior_object_getset[] =
    887  1.1  christos {
    888  1.1  christos   { "num", infpy_get_num, NULL, "ID of inferior, as assigned by GDB.", NULL },
    889  1.1  christos   { "pid", infpy_get_pid, NULL, "PID of inferior, as assigned by the OS.",
    890  1.1  christos     NULL },
    891  1.1  christos   { "was_attached", infpy_get_was_attached, NULL,
    892  1.1  christos     "True if the inferior was created using 'attach'.", NULL },
    893  1.1  christos   { NULL }
    894  1.1  christos };
    895  1.1  christos 
    896  1.1  christos static PyMethodDef inferior_object_methods[] =
    897  1.1  christos {
    898  1.1  christos   { "is_valid", infpy_is_valid, METH_NOARGS,
    899  1.1  christos     "is_valid () -> Boolean.\n\
    900  1.1  christos Return true if this inferior is valid, false if not." },
    901  1.1  christos   { "threads", infpy_threads, METH_NOARGS,
    902  1.1  christos     "Return all the threads of this inferior." },
    903  1.1  christos   { "read_memory", (PyCFunction) infpy_read_memory,
    904  1.1  christos     METH_VARARGS | METH_KEYWORDS,
    905  1.1  christos     "read_memory (address, length) -> buffer\n\
    906  1.1  christos Return a buffer object for reading from the inferior's memory." },
    907  1.1  christos   { "write_memory", (PyCFunction) infpy_write_memory,
    908  1.1  christos     METH_VARARGS | METH_KEYWORDS,
    909  1.1  christos     "write_memory (address, buffer [, length])\n\
    910  1.1  christos Write the given buffer object to the inferior's memory." },
    911  1.1  christos   { "search_memory", (PyCFunction) infpy_search_memory,
    912  1.1  christos     METH_VARARGS | METH_KEYWORDS,
    913  1.1  christos     "search_memory (address, length, pattern) -> long\n\
    914  1.1  christos Return a long with the address of a match, or None." },
    915  1.1  christos   { NULL }
    916  1.1  christos };
    917  1.1  christos 
    918  1.1  christos static PyTypeObject inferior_object_type =
    919  1.1  christos {
    920  1.1  christos   PyVarObject_HEAD_INIT (NULL, 0)
    921  1.1  christos   "gdb.Inferior",		  /* tp_name */
    922  1.1  christos   sizeof (inferior_object),	  /* tp_basicsize */
    923  1.1  christos   0,				  /* tp_itemsize */
    924  1.1  christos   infpy_dealloc,		  /* tp_dealloc */
    925  1.1  christos   0,				  /* tp_print */
    926  1.1  christos   0,				  /* tp_getattr */
    927  1.1  christos   0,				  /* tp_setattr */
    928  1.1  christos   0,				  /* tp_compare */
    929  1.1  christos   0,				  /* tp_repr */
    930  1.1  christos   0,				  /* tp_as_number */
    931  1.1  christos   0,				  /* tp_as_sequence */
    932  1.1  christos   0,				  /* tp_as_mapping */
    933  1.1  christos   0,				  /* tp_hash  */
    934  1.1  christos   0,				  /* tp_call */
    935  1.1  christos   0,				  /* tp_str */
    936  1.1  christos   0,				  /* tp_getattro */
    937  1.1  christos   0,				  /* tp_setattro */
    938  1.1  christos   0,				  /* tp_as_buffer */
    939  1.1  christos   Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_ITER,  /* tp_flags */
    940  1.1  christos   "GDB inferior object",	  /* tp_doc */
    941  1.1  christos   0,				  /* tp_traverse */
    942  1.1  christos   0,				  /* tp_clear */
    943  1.1  christos   0,				  /* tp_richcompare */
    944  1.1  christos   0,				  /* tp_weaklistoffset */
    945  1.1  christos   0,				  /* tp_iter */
    946  1.1  christos   0,				  /* tp_iternext */
    947  1.1  christos   inferior_object_methods,	  /* tp_methods */
    948  1.1  christos   0,				  /* tp_members */
    949  1.1  christos   inferior_object_getset,	  /* tp_getset */
    950  1.1  christos   0,				  /* tp_base */
    951  1.1  christos   0,				  /* tp_dict */
    952  1.1  christos   0,				  /* tp_descr_get */
    953  1.1  christos   0,				  /* tp_descr_set */
    954  1.1  christos   0,				  /* tp_dictoffset */
    955  1.1  christos   0,				  /* tp_init */
    956  1.1  christos   0				  /* tp_alloc */
    957  1.1  christos };
    958  1.1  christos 
    959  1.1  christos #ifdef IS_PY3K
    960  1.1  christos 
    961  1.1  christos static PyBufferProcs buffer_procs =
    962  1.1  christos {
    963  1.1  christos   get_buffer
    964  1.1  christos };
    965  1.1  christos 
    966  1.1  christos #else
    967  1.1  christos 
    968  1.1  christos /* Python doesn't provide a decent way to get compatibility here.  */
    969  1.1  christos #if HAVE_LIBPYTHON2_4
    970  1.1  christos #define CHARBUFFERPROC_NAME getcharbufferproc
    971  1.1  christos #else
    972  1.1  christos #define CHARBUFFERPROC_NAME charbufferproc
    973  1.1  christos #endif
    974  1.1  christos 
    975  1.1  christos static PyBufferProcs buffer_procs = {
    976  1.1  christos   get_read_buffer,
    977  1.1  christos   get_write_buffer,
    978  1.1  christos   get_seg_count,
    979  1.1  christos   /* The cast here works around a difference between Python 2.4 and
    980  1.1  christos      Python 2.5.  */
    981  1.1  christos   (CHARBUFFERPROC_NAME) get_char_buffer
    982  1.1  christos };
    983  1.1  christos #endif	/* IS_PY3K */
    984  1.1  christos 
    985  1.1  christos static PyTypeObject membuf_object_type = {
    986  1.1  christos   PyVarObject_HEAD_INIT (NULL, 0)
    987  1.1  christos   "gdb.Membuf",			  /*tp_name*/
    988  1.1  christos   sizeof (membuf_object),	  /*tp_basicsize*/
    989  1.1  christos   0,				  /*tp_itemsize*/
    990  1.1  christos   mbpy_dealloc,			  /*tp_dealloc*/
    991  1.1  christos   0,				  /*tp_print*/
    992  1.1  christos   0,				  /*tp_getattr*/
    993  1.1  christos   0,				  /*tp_setattr*/
    994  1.1  christos   0,				  /*tp_compare*/
    995  1.1  christos   0,				  /*tp_repr*/
    996  1.1  christos   0,				  /*tp_as_number*/
    997  1.1  christos   0,				  /*tp_as_sequence*/
    998  1.1  christos   0,				  /*tp_as_mapping*/
    999  1.1  christos   0,				  /*tp_hash */
   1000  1.1  christos   0,				  /*tp_call*/
   1001  1.1  christos   mbpy_str,			  /*tp_str*/
   1002  1.1  christos   0,				  /*tp_getattro*/
   1003  1.1  christos   0,				  /*tp_setattro*/
   1004  1.1  christos   &buffer_procs,		  /*tp_as_buffer*/
   1005  1.1  christos   Py_TPFLAGS_DEFAULT,		  /*tp_flags*/
   1006  1.1  christos   "GDB memory buffer object", 	  /*tp_doc*/
   1007  1.1  christos   0,				  /* tp_traverse */
   1008  1.1  christos   0,				  /* tp_clear */
   1009  1.1  christos   0,				  /* tp_richcompare */
   1010  1.1  christos   0,				  /* tp_weaklistoffset */
   1011  1.1  christos   0,				  /* tp_iter */
   1012  1.1  christos   0,				  /* tp_iternext */
   1013  1.1  christos   0,				  /* tp_methods */
   1014  1.1  christos   0,				  /* tp_members */
   1015  1.1  christos   0,				  /* tp_getset */
   1016  1.1  christos   0,				  /* tp_base */
   1017  1.1  christos   0,				  /* tp_dict */
   1018  1.1  christos   0,				  /* tp_descr_get */
   1019  1.1  christos   0,				  /* tp_descr_set */
   1020  1.1  christos   0,				  /* tp_dictoffset */
   1021  1.1  christos   0,				  /* tp_init */
   1022  1.1  christos   0,				  /* tp_alloc */
   1023  1.1  christos };
   1024