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